Re-wording per previous request... I am dynamically adding TableLayouts at runtime. A view rundown looks like this... LinearLayout->ScrollView->TableLayout->Loop creating TableLayouts and TableRows at runtime. So basically I am looping and adding the following:
for(i=0.... i++)
Left Middle Right
Bottom
Now everything gets added correctly, looks correct and scrolls correctly. However I am attempting to create an onTouch event which changes the background on the touched dynamically created TableLayout. Inside the onTouch for each dynamically created TableLayout I have a onTouch event that when called does the following:
tableLayoutRow1.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("OnTouch", "OnTouch Event for " + Integer.toString(v.getId()) + " event:" + Integer.toString(event.getAction()));
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
Log.d("OnTouch", "Changing to GREEN");
v.setBackgroundColor(Color.GRAY);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_MOVE:
Log.d("OnTouch", "Changing to BLACK");
v.setBackgroundColor(Color.BLACK);
break;
}
return true;
}
});
Whenever it calls the setBackgroundColor it messes up the alignment of every one of the dynamically created TableLayouts and makes them look like this:
LeftMiddleRight
Bottom
The entire code follows. I hope this is clear now.
public class TableActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
linearLayout.setWeightSum(1);
ScrollView scrollView = new ScrollView(this);
scrollView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
TableLayout tableLayoutMaster = new TableLayout(this);
tableLayoutMaster.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
// <table>
// <tr><td><table><tr><td></td><td></td><td></td></tr></table></td></tr>
// <tr><td></td></tr>
// </table>
for(int i=0; i<=30; i++)
{
TableLayout tableLayoutRow1 = new TableLayout(this);
tableLayoutRow1.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
tableLayoutRow1.setColumnStretchable(2, true);
//tableLayoutRow1.setBackgroundColor(Color.GREEN);
TableRow tableRow = new TableRow(this);
ImageView left_column = new ImageView(this);
left_column.setImageResource(17301550);
tableRow.addView(left_column);
TextView middle_column = new TextView(this);
middle_column.setText("Left Column:" + Integer.toString(i));
middle_column.setTypeface(null, Typeface.BOLD);
middle_column.setGravity(Gravity.LEFT);
middle_column.setPadding(5, 0, 0, 0);
tableRow.addView(middle_column);
TextView right_column = new TextView(this);
right_column.setText("Right Column:" + Integer.toString(i));
right_column.setTypeface(null, Typeface.BOLD);
right_column.setGravity(Gravity.RIGHT);
right_column.setPadding(0, 0, 5, 0);
tableRow.addView(right_column);
tableLayoutRow1.addView(tableRow);
tableRow = null;
// now for the bottom row
TextView bottom_column = new TextView(this);
bot开发者_如何学编程tom_column.setText("Starting activity com.developersinfo.testing.TableActivity on device emulator-5554");
bottom_column.setTextSize(12f);
bottom_column.setGravity(Gravity.LEFT);
bottom_column.setPadding(30, 0, 0, 0);
tableLayoutRow1.addView(bottom_column);
tableLayoutRow1.setId(i);
tableLayoutRow1.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
// TODO Auto-generated method stub
Log.d("OnFocusChange", "OnFocusChange Event for " + Integer.toString(v.getId()));
}
});
tableLayoutRow1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.d("OnClick", "OnClick Event for " + Integer.toString(v.getId()));
}
});
tableLayoutRow1.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("OnTouch", "OnTouch Event for " + Integer.toString(v.getId()) + " event:" + Integer.toString(event.getAction()));
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
Log.d("OnTouch", "Changing to GREEN");
v.setBackgroundColor(Color.GRAY);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_MOVE:
Log.d("OnTouch", "Changing to BLACK");
v.setBackgroundColor(Color.BLACK);
break;
}
return true;
}
});
// now add to master table
tableLayoutMaster.addView(tableLayoutRow1);
}
scrollView.addView(tableLayoutMaster);
linearLayout.addView(scrollView);
setContentView(linearLayout);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}
I have tried everything I can think of to keep it from doing this but so far I am unable to explain why or how to correct it. As long as I do not call the setBackgroundColor inside the onTouch everything scrolls and aligns as expected.
I had pretty much exactly the same problem you are having in a project I worked. I used long time trying to figure out what's wrong but at the end only solution was to ditch the table layout and and go for something else. It looks like a bug in the system to me.
I recommend using RelativeLayout instead if possible.
i test your code in one activity, and i don't think and don't see the alignment is bad, when touching the table row it looks good... (i mean the onTouchEvent does not mess the layout aligment. Anyway, i suggest you a ListActivity if do so, you can set a selector background to the inner views, and a color or drawable to any state of the view, selected, pressed... and more... and inside of inner views you can use a relative layout or another layout... There is another thing, ListActivity uses ListAdapters that are very efficient, Views are virtualized thats mean the device does not have to hold all views, only those that are visible and not the 30*4 views that you hold actually.
Thanks to both of you for the insight. I will look at the ListActivity and ListAdapters but this was more of a understanding expedition than anything at this point. I have this working using the sledgehammer approach as suggested by Juhani.
public class TestLayout extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ScrollView scrollView = new ScrollView(this);
scrollView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
LinearLayout layout_master = new LinearLayout(this);
layout_master.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
layout_master.setOrientation(LinearLayout.VERTICAL);
scrollView.addView(layout_master);
for(int i=1; i<=30; i++)
{
RelativeLayout layout_body = new RelativeLayout(this);
TextView left_Column = new TextView(this);
left_Column.setId(i);
left_Column.setText("Left");
left_Column.setGravity(Gravity.LEFT);
left_Column.setPadding(5, 0, 5, 0);
TextView middle_Column = new TextView(this);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.RIGHT_OF, left_Column.getId());
middle_Column.setLayoutParams(lp);
middle_Column.setText("Middle");
middle_Column.setGravity(Gravity.LEFT);
middle_Column.setPadding(5, 0, 5, 0);
TextView right_Column = new TextView(this);
lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
right_Column.setLayoutParams(lp);
right_Column.setText("Right");
right_Column.setGravity(Gravity.RIGHT);
right_Column.setPadding(5, 0, 5, 0);
layout_body.addView(left_Column);
layout_body.addView(middle_Column);
layout_body.addView(right_Column);
TextView bottom = new TextView(this);
bottom.setId(1000 + i);
lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.BELOW, left_Column.getId());
bottom.setLayoutParams(lp);
bottom.setText("Starting activity com.developersinfo.testing.TestLayout on device emulator-5554");
layout_body.addView(bottom);
View view_hr = new View(this);
view_hr.setMinimumWidth(layout_body.getWidth());
view_hr.setMinimumHeight(1);
view_hr.setBackgroundColor(Color.GRAY);
lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.BELOW, bottom.getId());
view_hr.setLayoutParams(lp);
layout_body.addView(view_hr);
layout_body.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
Log.d("OnTouch", "Changing to GREEN");
v.setBackgroundColor(Color.GREEN);
break;
default:
Log.d("OnTouch", "Changing to BLACK");
v.setBackgroundColor(Color.BLACK);
break;
}
return true;
}
});
layout_master.addView(layout_body);
}
//scrollView.addView(layout_master);
setContentView(scrollView);
}
}
精彩评论