setBackgroundColor causing TableLayout alignment problems - android

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);
bottom_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);
}
}

Related

How can I change the size of my textview added programmatically on layout.addview

On the following code, I programatically added the textview on the layout.addview
textView = new TextView(Chat.this);
/*textView.setTypeface(null, Typeface.BOLD);*/
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
getResources().getDimension(R.dimen.original));
textView.setText(message);
final ImageView imgView = new ImageView(Chat.this);
LinearLayout childLayout = new LinearLayout(Chat.this);
LinearLayout.LayoutParams lp2 = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
lp2.setMargins(0, 0, 0, 0);
LinearLayout.LayoutParams LPimgView = new LinearLayout.LayoutParams(
100,
100 /*ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT*/);
I also implemented a menu where a user can choose to resize the textviews on his screen by choosing one of the options given. here's the code:
public void createDialogBoxWithRbutton(){
/*totalMsg = countChatWithMsg1 + countChatWithMsg2;*/
AlertDialog.Builder builder = new AlertDialog.Builder(Chat.this);
builder.setTitle("Select From the Options");
builder.setSingleChoiceItems(values, -1, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int item) {
/*for(int i = 0; i < layout.getChildCount(); i++){
Toast.makeText(Chat.this, "Total messages: " + i, Toast.LENGTH_SHORT).show();
}*/
switch (item){
case 0:
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.font1));
/*textSize = 15;*/
break;
case 1:
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.font2));
/*textSize = 20;*/
break;
case 2:
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.font3));
/* textSize = 30;*/
break;
}
alertDialog1.dismiss();
}
});
alertDialog1 = builder.create();
alertDialog1.show();
}
But what happen is that when I click an option, it is only the least textview on the layout view that is being changed. The other textview remains on its size.
What could be the cause of this?
you can use simple property for set textsize programatically
your_textview.setTextSize(24); // in sp

How to change the color of textview backgrounds when swiped?

I am developing an android word search app and I have dynamically created a tablelayout with textviews on it to hold each letters. I want to change the background color of those textviews when the user's finger swipe on the letter grid.
This is the code for the table layout:
public void createGrid(char[][] input) {
RelativeLayout rl = (RelativeLayout)findViewById(R.id.rl);
TableLayout table = (TableLayout) findViewById(R.id.mainLayout);
table.setTag(1);
Typeface font = Typeface.createFromAsset(getAssets(), "kg.ttf");
int j;
for (int i = 0; i < input.length; i++) {
LinearLayout rowLayout = new LinearLayout(this);
rowLayout.setOrientation(LinearLayout.HORIZONTAL);
rowLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
final TableRow row = new TableRow(this);
row.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
row.setGravity(Gravity.CENTER_HORIZONTAL);
for (j = 0; j < input.length; j++) {
final TextView text = new TextView(this);
Character temp = input[i][j];
text.setTag(i);
text.setText(temp.toString());
text.setPadding(20, 20, 20, 20);
text.setTag(i);
text.setTextSize(txtSize);
text.setTypeface(font);
text.setGravity(Gravity.CENTER);
text.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
view.setBackgroundColor(Color.parseColor("#c03768b7"));
((TextView)view).setTextColor(Color.WHITE);
}
});
row.addView(text);
row.getChildAt(j);
}
table.addView(row);
}
}
And as you can see, I assigned OnClickListeners on each TextViews. But I want a hassle-free highlighting so, is there a way to change that to swiping and not clicking each textviews?
Any comments, answers, and suggestions is very much appreciated.
EDIT:
What I'm trying to do is change the color of the letters in text as the text is swiped.
Detect the Swipe like mentioned below and implement the function to change the color of textview background
text.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
x1 = event.getX();
y1 = event.getY();
t1 = System.currentTimeMillis();
return true;
case MotionEvent.ACTION_UP:
x2 = event.getX();
y2 = event.getY();
t2 = System.currentTimeMillis();
if (x1 > x2) {
Toast.makeText(getActivity(), "Left swipe", Toast.LENGTH_SHORT).show();
// Insert your code to change the color of the textview background.
v.setBackgroundColor(Color.parseColor("#c03768b7"));
} else if (x2 > x1) {
Toast.makeText(getActivity(), "Right swipe", Toast.LENGTH_SHORT).show();
v.setBackgroundColor(Color.parseColor("#c03768b7"));
// Insert your code to change the color of the textview background.
}
return true;
}
return false;
}

Setting TextView on position x,y

Hello I want to display a String on a TextView when the user touches a button. But I want this TextView to be shown on the same position where the user touches the screen. At the moment I have following code but it doesnt work out:
private void set(Integer name, Float x, Float y, Typeface font) {
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT);
layoutParams.setMargins(10, 1, 10, 1);
RelativeLayout nlap = new RelativeLayout(this);
nlap.setLayoutParams(layoutParams);
TextView tv1 = new TextView(this);
tv1.setX(x);
tv1.setY(y);
tv1.setText("+ " + String.valueOf(name));
tv1.setTypeface(font);
tv1.setGravity(Gravity.CENTER);
tv1.setTextSize(20);
nlap.addView(tv1);
}
And in the OnTouchListener:
int action = motionEvent.getAction();
int x = (int)motionEvent.getX();
int y = (int)motionEvent.getY();
set(multiplicator, Float.intBitsToFloat(x), Float.intBitsToFloat(y), font);
I hope you can help me. Thank You!
Declare textView global to that activity
TextView tv;
then in oncreate() method
tv=(TextView) findViewById(R.id.your_xml_textview);
tv.setText("your desired text");
tv.setVisibility(View.INVISIBLE);
Or you can simply use android:visibility="invisible" in your xml
Now ontouch of the screen we get the co ordinate and put the textView on that point by below code
#Override
public boolean onTouchEvent(MotionEvent event) {
int corx = (int)event.getX();
int cory = (int)event.getY();
tv.setX(corx);
tv.setY(cory);
tv.setVisibility(View.VISIBLE);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
}
return false;
}

Add ImageView to FingerPaint View

I've created fingerpaint app. from finger paint android example API.
(SAMPLE: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android-apps/2.2_r1.1/com/example/android/apis/graphics/FingerPaint.java)
Now i've created an function to create a bitmap from paint (and move). This is my code:
public void addProgrammatlyImage(int pos[], String filePath){
// Let's create the missing ImageView
ImageView image = new ImageView(this);
// Now the layout parameters, these are a little tricky at first
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
image.setScaleType(ImageView.ScaleType.MATRIX);
Bitmap selectedImage = BitmapFactory.decodeFile(filePath);
image.setImageBitmap(selectedImage);
image.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
System.out.println("TOUCH!!");
switch(event.getActionMasked())
{
case MotionEvent.ACTION_DOWN:
offset_x = (int)event.getX();
offset_y = (int)event.getY();
selected_item = v;
break;
default:
break;
}
return false;
}
});
// Let's get the root layout and add our ImageView
FrameLayout layout = (FrameLayout) findViewById(R.id.vg1);
layout.setBackgroundColor(getResources().getColor(R.color.xxx));
layout.bringToFront();
((FrameLayout) layout).addView(image, 0, params);
}
My problem is:
if inflate the new image on the same level of fingerpaint view (MyView class in the sample), disappear on the background (fingerpaint is in front of the image).
i'm unable to insert image as child of MyView. In this case there is a problem when inflate the image: classcast exception, can't cast view (MyViewClass) to ViewGroup.
Can you help me please??

How to set OnTouchListener for dynamically created views?

I have two layouts, one LinearLayout and one RelativeLayout. In the LinearLayout I have 10 images. When I click one image, it is added to the RelativeLayout. Similar event is given for all 10 images. In the RelativeLayout, I have set a OnTouchListener to the ImageView added from the LinearLayout. But my problem is, onTouch only works for the ImageView which is recently added but when I try to touch previously added images, it doesn't work. I want to add listener for all images added in the relative layout.
Below is what I have tried so far:
for(int i = 0; i < data.length; i++){
image[i] = new ImageView(getApplicationContext());
try{
// int imgID = getResources().getIdentifier(data[i], null, getPackageName());
image[i].setImageResource(data[i]);
}catch(Exception e){
int imgID = getResources().getIdentifier("nia", "drawable", "package");
image[i].setImageResource(imgID);
}
LinearLayout.LayoutParams LEye = new LinearLayout.LayoutParams(
100 , 70);
LEye.leftMargin=20;
image[i].setLayoutParams(LEye);
shapeImageContainer.addView(image[i]); //shapeImageContainer is the Linear Layout
final int c=i;
image[i].setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//addContentView( addIcon(), new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT ) );
Toast.makeText(NewProject.this, "Position "+c, Toast.LENGTH_SHORT).show();
rootView.addView(addIcon(c)); //rootView is the Relative layout
}
});
//image[i].setOnTouchListener(MyOnTouchListener);
}
private ImageView addIcon(int c){
item = new ImageView(this);
item.setImageResource(data[c]);
item.setAdjustViewBounds(true);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(100, 60 );
if( mIconIdCounter != 1 ){
params.addRule(RelativeLayout.RIGHT_OF,c-1);
}
item.setLayoutParams( params );
item.setId( mIconIdCounter );
++mIconIdCounter;
item.setOnTouchListener(MyOnTouchListener);
return item;
}
OnTouchListener MyOnTouchListener = new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
// scroll.setEnabled(false);
// horizontal.setEnabled(false);
// scroll.setVisibility(View.GONE);
// horizontal.setVisibility(View.GONE);
RelativeLayout.LayoutParams layoutParams2 = (RelativeLayout.LayoutParams) item.getLayoutParams();
switch(event.getActionMasked())
{
case MotionEvent.ACTION_MOVE:
scroll.requestDisallowInterceptTouchEvent(true);
horizontal.requestDisallowInterceptTouchEvent(true);
int x_cord = (int) event.getRawX();
int y_cord = (int) event.getRawY();
//right margin
if (x_cord > windowwidth) {
x_cord = windowwidth-10;
}
// left margin original
if (x_cord <68) {
x_cord = 68;
}
// left margin original
if (y_cord <68) {
y_cord = 68;
}
if (y_cord > windowheight) {
y_cord = windowheight-10;
}
// tv.setText(String.valueOf(y_cord));
layoutParams2.leftMargin = x_cord -60;
layoutParams2.topMargin = y_cord -65;
item.setLayoutParams(layoutParams2);
break;
default:
break;
}
return true;
}
};
But my problem is, onTouch only works for the imageview which is
recently added but when I try to touch previously added images,it
doesn't work.
That's because in the OnTouchListener you use the item field to do your work(which will always point to the last ImageView added as you wrote the code) instead of using the View for which the listener is called. Try something like this:
RelativeLayout.LayoutParams layoutParams2 = (RelativeLayout.LayoutParams) v.getLayoutParams();
// rest of the onTouch callback...
v.setLayoutParams(layoutParams2);

Categories

Resources