Layouts - MATCH_PARENT hides elements - android

I'm preparing layout for list of countries shown in categories. I have problem formatting my layout. I want category titles (bigger ones) to be "100% width", so far they are WRAP_CONTENT formatted (blue colour is for testing purposes):
I used the following code:
TableLayout table = new TableLayout(this);
table.setPadding(24, 14, 24, 24);
table.setStretchAllColumns(true);
table.setShrinkAllColumns(true);
// ...
TableRow titleRow = new TableRow(this);
titleRow.setGravity(Gravity.CENTER_HORIZONTAL);
titleRow.setPadding(0, 18, 0, 8);
titleRow.setBackgroundColor(Color.BLUE);
TextView title = new TextView(this);
title.setText("TEST TITLE"); //title.setText(currentContinent);
title.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18);
title.setGravity(Gravity.CENTER);
title.setBackgroundColor(Color.DKGRAY);
title.setPadding(0, 6, 0, 8);
titleRow.addView(title);
table.addView(titleRow, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
I changed last part of code to make TextView filling parent (TableRow):
titleRow.addView(title, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
table.addView(titleRow, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
But then my TextView dissapears!
Debug view http://www.wysyper.pl/u/4417tahfcvnb.jpeg
What can cause the problem?

I trust that you have a good reason not to use XML layouts for this, which should make your life a lot less code-filled and eliminate some potential bugs.
Have you tried it using instances of the proper LayoutParams subclass for your parent views? Each view added to a TableLayout should use instances of TableLayout.LayoutParams. Likewise TableRow expects instances of TableRow.LayoutParams.
If that doesn't fix it, I recommend building the layout in XML instead of code.

Related

How to modify ImageButton layout

I have a TableRow where I add some items to be shown and everything goes alright. Nevertheless, when I want to add a layout-modified button it just does not appear to be painted. Here is the code:
ImageButton botonBorrar = new ImageButton(this);
botonBorrar.setImageResource(R.drawable.discard_light);
LinearLayout.LayoutParams buttonParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.MATCH_PARENT);
buttonParams.setMargins(15, 10, 10, 10);
botonBorrar.setLayoutParams(buttonParams);
myRow.addView(botonBorrar);
What could be wrong here?. I have followed a lot of posts about this but nothing seems to correct my problem.
Thanks in advance.
I suppose you should use TableRow.LayoutParams instead of LinearLayout.LayoutParams.
The children of a TableRow do not need to specify the layout_width and layout_height attributes in the XML file. (http://developer.android.com/reference/android/widget/TableRow.html)
So you can add button to the view first and then get already generated layoutparams and modify them:
myRow.addView(botonBorrar);
TableRow.LayoutParams buttonParams = (TableRow.LayoutParams)bottonBorrar.getLayoutParams();
buttonParams.setMargins(15, 10, 10, 10);
//botonBorrar.setLayoutParams(buttonParams); - if you add button to the view, you do not have to set modified layout params explicitly.

Android: Tablerow multiline textview clipping vertically

I am dynamically adding rows with two columns to a table. One of the columns holds text that will spread across multiple lines. I've added the weight on the layout parameters for the textview so it no longer clipps outside of the screen, but it seems to be restricted to two and a half lines showing in the table, regardless of how long the multiline text is. The table is just defined in xml and everything else is done programmatically.
TableRow.LayoutParams rowParams = new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT, TableRow.LayoutParams.WRAP_CONTENT);
TableRow.LayoutParams paramsStar = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT);
paramsStar.setMargins(0,0,40,0);
TableRow.LayoutParams paramsText = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.FILL_PARENT, (float)1.0);
TableRow tr = new TableRow(this);
tr.setLayoutParams(rowParams);
TextView viewStar = new TextView(this);
viewStar.setTextSize((float) 30.0);
viewStar.setText("*");
viewStar.setLayoutParams(paramsStar);
viewStar.setTypeface(Typeface.DEFAULT_BOLD, 2);
TextView viewText = new TextView(this);
viewText.setText("Long multiline text piece"); //<--- Here the long text goes
viewText.setLayoutParams(paramsText);
tr.addView(viewStar);
tr.addView(viewText);
table.addView(tr, rowParams);
How do i fix this vertical clipping?
Screenshot of the problem below:
Here is the link showing the problem
I've found the root of the problem. The first column values textsize made the multiline text clip. If i reduce the textsize, the problem disappears.
I cant explain why though.
Another answer I'll drop in here: Android measures table row height in a very non-intuitive way. If you have 2 TextView(s), one for each column of a TableRow, you need to ensure that whatever top and bottom padding you've set for the first TextView is set identically for the 2nd TextView or you will get strange things like content clipping and weird positioning of the 2nd TextView.

How can I add separating lines between my TableRows that are created programmatically?

I have a TableLayout that is created programmatically in an Android project. I keep adding TableRows as long as there are more rows fetched from the database. Now I want to add separating lines, like a border, between the TableRows.
In my other TableLayout that I created statically from XML I used a View as a separator, style with a style.xml.
I tried adding a View to the tablelayout like so:
View v=new View(this);
v.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
v.setBackgroundResource(R.drawable.rowseparator_shape);
tr.addView(mTvDate);
tr.addView(mTvResult);
tl.addView(tr);
tl.addView(v);
But it only gets added once after all the collected TableRows. What would be a smart way of adding one View for each tr added? Or should I use something else alltogether?
View v = new View(this);
v.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT, 1));
v.setBackgroundColor(Color.rgb(51, 51, 51));
tr.addView(mTvDate);
tr.addView(mTvResult);
tl.addView(tr);
tl.addView(v);
Here I'm creating a view that is one pixel high with a specific background color. This works for me.
Thanks to Madhusuthanan for this. I spent a while searching for how to do this to simply separate TextViews with a horizontal line. I was creating my view programmatically (without using a Table layout). Here is what I came up with based on the above answer:
View line = new View(this);
line.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, 1));
line.setBackgroundColor(Color.rgb(51, 51, 51));
layout.addView(line);
Simple! Hope this helps someone else!
You can use Listview that will be easiler and better than doing this.

How to Change Margin of TextView

I have TextView added Programmatically in to LinearLayout and on some external events I want to decrease bottom margin of that TextView to -10, for that I tried following.
LinearLayout.LayoutParams lastTxtParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
lastTxtParams.setMargins(0, 0, 0, -10);
mOldTextView.setLayoutParams(lastTxtParams);
mOldTextView.invalidate();
Is the right way of modifying Margin of widget that has been added to View?
Some how it is not working.
TextView forgot_pswrd = (TextView) findViewById(R.id.ForgotPasswordText);
forgot_pswrd.setOnTouchListener(this);
LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
llp.setMargins(50, 0, 0, 0); // llp.setMargins(left, top, right, bottom);
forgot_pswrd.setLayoutParams(llp);
I did this and it worked perfectly.
Maybe as you are giving the value in -ve, that's why your code is not working.
You just put this code where you are creating the reference of the view.
Your layout in xml probably already has a layout_margin(Left|Right|etc) attribute in it, which means you need to access the object generated by that xml and modify it.
I found this solution to be very simple:
ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) mTextView
.getLayoutParams();
mlp.setMargins(adjustmentPxs, 0, 0, 0);
break;
Get the LayoutParams instance of your textview, downcast it to MarginLayoutParams, and use the setMargins method to set the margins.
This one is tricky problem, i set margin to textview in a row of a table layout.
see the below:
TableLayout tl = new TableLayout(this);
tl.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
TableRow tr = new TableRow(this);
tr.setBackgroundResource(R.color.rowColor);
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.setMargins(4, 4, 4, 4);
TextView tv = new TextView(this);
tv.setBackgroundResource(R.color.textviewColor);
tv.setText("hello");
tr.addView(tv, params);
TextView tv2 = new TextView(this);
tv2.setBackgroundResource(R.color.textviewColor);
tv2.setText("hi");
tr.addView(tv2, params);
tl.addView(tr);
setContentView(tl);
the class needed to import for LayoutParams for use in a table row is :
import android.widget.**TableRow**.LayoutParams;
important to note that i added the class for table row. similarly many other classes are available to use LayoutParams like:
import android.widget.**RelativeLayout**.LayoutParams;
import android.widget.LinearLayout.LayoutParams;
so use accordingly.
setMargins() sets the INNER margins of the TextView, not the layout-margins. Is that what you want to do? This two different margins can be quite complicated.
If you want to set the layout margins, change the LayoutParams of the TextView (textview.getLayoutParams(), then change the parameters on the returned LayoutParams object).
You don't need to change anything on your LinearLayout.
Regards,
Oliver
TextView does not support setMargins. Android docs say:
Even though a view can define a padding, it does not provide any support for margins. However, view groups provide such a support. Refer to ViewGroup and ViewGroup.MarginLayoutParams for further information.
Here is another approach...
When I've got to the same problem, I didn't like the suggested solutions here.
So, I've come up with another way:
I've inserted a TextView in the XML file between the two fields I wanted to separate with two important fields:
visibility set to "GONE" (doesn't occupy any space..)
height is set to whatever I needed the separation to be.
XML:
...//some view up here
<TextView
android:id="#+id/dialogSeparator"
android:layout_width="match_parent"
android:layout_height="30dp"
android:visibility="gone"/>
...//some view down here
Now, I the code, all I needed to do it simple change the visibility to invisible (i.e. it's there, and taking the needed space, but it's unseen)
JAVA:
TextView tvSeparator = (TextView)activity.findViewById(R.id.dialogSeparator);
tvSeparator.setVisibility(View.INVISIBLE);
//Inside an activity extended class I can use 'this' instead of 'activity'.
Viola...I got the needed margin.
BTW, This solution is for LinearLayout with vertical orientation, but you can do it with different layouts.
Hope this helps.
You were probably changing the layout margin after it has been drawn. mOldTextView.invalidate() is useless. you needed to call requestLayout() on the parent to relayout the new configuration. When you moved the layout changing code before the drawing took place, everything worked fine.
TextView tv = (TextView)findViewById(R.id.item_title));
RelativeLayout.LayoutParams mRelativelp = (RelativeLayout.LayoutParams) tv
.getLayoutParams();
mRelativelp.setMargins(DptoPxConvertion(15), 0, DptoPxConvertion (15), 0);
tv.setLayoutParams(mRelativelp);
private int DptoPxConvertion(int dpValue)
{
return (int)((dpValue * mContext.getResources().getDisplayMetrics().density) + 0.5);
}
getLayoutParams() of textview should be casted to the corresponding Params based on the Parent of the textview in xml.
<RelativeLayout>
<TextView
android:id="#+id/item_title">
</RelativeLayout>
To render the same real size on different devices use DptoPxConvertion() method which I have used above. setMargin(left,top,right,bottom) params will take values in pixel not in dp. For further reference see this Link Answer

android: two issues using Tablerow+TextView in Tablelayout

I am using Tablerow+TextView to make a simple view for blog posts and their replies. In each TableRow I put a TextView in. Now I have two issues:
The text which is longer than the screen won't automatically wrap up to be multi-line. Is it by design of TableRow? I've already set tr_content.setSingleLine(false); [update] This has been addressed, I think I should change Fill_parent to be Wrap_content in textView.tr_author_time.setLayoutParams(new LayoutParams(
LayoutParams.**WRAP_CONTENT**,
LayoutParams.WRAP_CONTENT));
The Table won't scroll like ListView. My rows are more than the screen size. I expect the table could be scrolled down for viewing just like ListView. Is that possible?
Here is my code:
TableLayout tl = (TableLayout) findViewById(R.id.article_content_table);
TextView tr_title = new TextView(this);
TextView tr_author_time = new TextView(this);
TextView tr_content = new TextView(this);
TableRow tr = new TableRow(this);
for(int i = 0; i < BlogPost.size(); i++){
try{
// add the author, time
tr = new TableRow(this);
/////////////////add author+time row
BlogPost article = mBlogPost.get(i);
tr_author_time = new TextView(this);
tr_author_time.setText(article.author+"("+
article.post_time+")");
tr_author_time.setTextColor(getResources().getColor(R.color.black));
tr_author_time.setGravity(0x03);
tr_author_time.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
tr.addView(tr_author_time);
tl.addView(tr,new TableLayout.LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
////////////////////// then add content row
tr = new TableRow(this);
tr_content = new TextView(this);
tr_content.setText(article.content);
tr_content.setSingleLine(false);
tr_content.setGravity(0x03);
tr_content.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
tr.addView(tr_content);
tr.setBackgroundResource(R.color.white);
tl.addView(tr,new TableLayout.LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
}
A more appropriate thing to do for wrapping items would have been to add android:shrinkColumns="*" or android:shrinkColumns="1" to the TableLayout, this would probably have fixed the wrapping issue.
For Details
This isn't really a complete answer, but it really seems like you're doing this the hard way.
Instead of constructing your TableRows manually, you should set them up in xml like this:
tablerow.xml:
<TableRow xmlns:android="http://schemas.android.com/apk/res/android">
<TextView android:id="#+id/content"
android:singleLine="false"
android:textAppearance="#style/someappearance" />
</TableRow>
Prior to your loop, get a reference to a LayoutInflater:
LayoutInflater inflater = getLayoutInflater();
Then, inside your loop, create an instance of tablerow using the LayoutInflater:
TableRow row = (TableRow)inflater.inflate(R.layout.tablerow, tl, false);
TextView content = (TextView)row.findViewById(R.id.content);
content.setText("this is the content");
tl.addView(row);
This will allow you to set your layout, appearance, layout params in xml making it much easier to read and debug.
For the scrolling problem, you'll need to add your TableLayout to a ScrollView. Something like this in your xml:
<ScrollView>
<TableLayout android:id="#+id/arcitle_content_table" />
</ScrollView>
To wrap text in table rows:
By default, TableLayout rows fit the width of their content, no matter it goes over the screen bounds. To get the wider-than-screen text cells to wrap to multi-line, use android:shrinkColumns attribute on TableLayout.
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:shrinkColumns="*" />
android:shrinkColumns is zero-based index of the columns to shrink. It removes unnecessary extra space from a column and shrinks it :
android:shrinkColumns="*" shrinks all columns
android:shrinkColumns="0" shrinks first column
android:shrinkColumns="1,2" shrinks the second and third columns
android:stretchColumns does the opposite. It stretches a column to the maximum available width.
Both "shrink" and "stretch" consider all rows of the table to compute space.
To scroll down a TableLayout:
If your TableLayout is higher than the screen, move it in a ScrollView.

Categories

Resources