I'm using a TableLayout in Android. Right now I have one TableRow with two items in it, and, below that, a TableRow with one item it it. It renders like this:
-----------------------------
| Cell 1 | Cell 2 |
-----------------------------
| Cell 3 |
---------------
What I want to do is make Cell 3 stretch across both upper cells, so it looks like this:
-----------------------------
| Cell 1 | Cell 2 |
-----------------------------
| Cell 3 |
-----------------------------
In HTML I'd use a COLSPAN.... how do I make this work in Android?
It seems that there is an attribute doing that :
layout_span
UPDATE:
This attribute must be applied to the children of the TableRow. NOT to the TableRow itself.
Just to complete the answer, the layout_span attribute must be added to the child, not to TableRow.
This snippet shows the third row of my tableLayout, which spans for 2 columns.
<TableLayout>
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_span="2"
android:text="#string/create" />
</TableRow>
</TableLayout>
And this is how you do it programmatically
//theChild in this case is the child of TableRow
TableRow.LayoutParams params = (TableRow.LayoutParams) theChild.getLayoutParams();
params.span = 2; //amount of columns you will span
theChild.setLayoutParams(params);
You have to use layout_weight to fill the entire row otherwise it still fills left or right column of table layout.
<TableRow
android:id="#+id/tableRow1"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_span="2"
android:layout_weight="1"
android:text="ClickMe" />
</TableRow>
Maybe this will help someone. I tried the solution with layout_span but this not working for me. So I solved the problem with this trick. Just use LinearLayout in place of TableRow where you need colspan, that's all.
use android:layout_span in child element of TableRow element
I've had some problem with rowspan, in case of TableRow, Textview and so on, generated with code. Even if Onimush answer seems to be good, it don't works with generated UI.
Here is a piece of code which.... don't work:
TableRow the_ligne_unidade = new TableRow(this);
the_ligne_unidade.setBackgroundColor(the_grey);
TextView my_unidade = new TextView(this);
my_unidade.setText(tsap_unidade_nom);
my_unidade.setTextSize(20);
my_unidade.setTypeface(null, Typeface.BOLD);
my_unidade.setVisibility(View.VISIBLE);
TableRow.LayoutParams the_param;
the_param = (TableRow.LayoutParams)my_unidade.getLayoutParams();
the_param.span = 3;
my_unidade.setLayoutParams(the_param);
// Put the TextView in the TableRow
the_ligne_unidade.addView(my_unidade);
The code seems to be OK but, when you reach the init of "the_params" it returns NULL.
On the other end, this code works like a charm:
TableRow the_ligne_unidade = new TableRow(this);
the_ligne_unidade.setBackgroundColor(the_grey);
TextView my_unidade = new TextView(this);
my_unidade.setText(tsap_unidade_nom);
my_unidade.setTextSize(20);
my_unidade.setTypeface(null, Typeface.BOLD);
my_unidade.setVisibility(View.VISIBLE);
// Put the TextView in the TableRow
the_ligne_unidade.addView(my_unidade);
// And now, we change the SPAN
TableRow.LayoutParams the_param;
the_param = (TableRow.LayoutParams)my_unidade.getLayoutParams();
the_param.span = 3;
my_unidade.setLayoutParams(the_param);
The only difference is that I push the Textview inside the TableRow before setting the span. And in this case, it works.
Hope this will help someone!
Actually It is pretty straight forward. This is my solution programmatically
TableLayout tableLayout = binding.tableLayout;
TableRow row = new TableRow(this);
TableRow.LayoutParams layoutParams = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT);
layoutParams.span = 4; // define no. of column span will row do
row.setLayoutParams(layoutParams);
TextView noDataTextView = new TextView(this);
noDataTextView.setText("No Data");
noDataTextView.setGravity(Gravity.CENTER);
noDataTextView.setLayoutParams(layoutParams); //This line will span your row
row.addView(noDataTextView);
tableLayout.addView(row, 1);
I think you need to wrap a layout around another one.
Have one Layout list vertically, inside have another one (or in this case, two) list horizontally.
I'm still finding it hard to nicely split interface to 50-50 portion in Android.
Related
I am creating a TableLayout to populate data dynamically. The problem I am facing here is that rows are not fitting horizontally into the screen.
This is my desired View,
\-----------------------------------------------------\
\| Student Name | Q1 | Q2 | Q3 | Total | % |\
\-----------------------------------------------------\
But the problem is,as Student Name is quite a large row (in width), the other rows are not fitting into the screen,
they are appearing like as shown below, from Q4 onwards all the rows are not fitting into the screen.
\------------------------------------\----------------
\| Student Name | Q1 | Q2 | Q3 \| Total | % |
\------------------------------------\----------------
This is the code I have used to create this view dynamically
students_table.xml
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="none">
<TableLayout
android:id="#+id/maintable"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</ScrollView>
QuestionPaperChecking.java
/** Table Row - Header */
trHeader = new TableRow(mContext);
trHeader.setLayoutParams(new TableLayout.LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
/* Student name */
TextView tvStudentName = new TextView(mContext);
tvStudentName.setText("Student Name");
tvStudentName.setTextColor(Color.WHITE);
tvStudentName.setGravity(Gravity.CENTER_VERTICAL);
tvStudentName.setTypeface(Typeface.DEFAULT, Typeface.BOLD);
tvStudentName.setBackgroundColor(getColor(mContext, R.color.background_blue_light));
tvStudentName.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
tvStudentName.setPadding(10, 10, 10, 10);
trHeader.addView(tvStudentName);
/* Question 1 */
TextView tvQ1 = new TextView(mContext);
tvQ1.setText("Q1");
tvQ1.setTextColor(Color.WHITE);
tvQ1.setTypeface(Typeface.DEFAULT, Typeface.BOLD);
tvQ1.setBackgroundColor(getColor(mContext, R.color.background_blue_light));
tvQ1.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
tvQ1.setPadding(10, 10, 10, 10);
tvQ1.setGravity(Gravity.CENTER_VERTICAL);
trHeader.addView(tvQ1);
//Similarly I have created all other rows
// Add the TableRow Header to the TableLayout
tblBattingSide.addView(trHeader, new TableLayout.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
Note: stretchColumns & shrinkColumns didnot work
I assume that you'd want to the text on the student's name to wrap to the next line.
The first thing to fix is the layout_width. Set the layout_width value of the ScrollView to match_parent/fill_parent. Do the same for the header TableRow (trHeader) as well as for each row you had to the table. Just to be clear, layout_width on the TableLayout itself should remain match_parent/fill_parent.
What this does is make sure all these views fit width-wise into the parents. This will still not completely solve the problem since the views in the rows still "push" the columns beyond the width of the table's container.
The second step is to set shrinkColumns on the TableLayout to "1". This will shrink the first column as much as possible until the table fits in the screen (or its container), and the text will wrap. Alternatively, you can set it to "*" if you want all columns to shrink.
I want to show a table row with three columns (TextView) but i want to divide the table row in three equal parts.
This is easily possible by setting a layoutWeightSum in TableRow in XML and making layout_weight=1 for all theww TextView.
But i adding the table at run time through java and not by xml.
All i know is the TableRow.LayoutParameter do not provide any thing for weightSum. How can i do this?
TableRow.LayoutParams pmRow = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT,
TableRow.LayoutParams.WRAP_CONTENT);
You can achieve this by following code.
TableLayout layout = //...findViewbyid
layout.setStretchAllColumns(true);
And make width 0dp to all the children (views) of TableRow like below.
<TextView
android:id="#+id/txt_no1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="hi" />
Note
Above is XML layout design, but you can create run time code also. Its just for demonstration.
I've got you covered, mate!
myTableRow.setWeightSum(float weightSum);
use pmRow.span=int value
like pmRow.span=3;
Create a LinearLayout xml (horizontal) with the three required Items ( TextViews). To add the row item at runtime, inflate the above said layout, and set text values and add it.
I'm got a stretched table and I want my checkbox to appear central also within the table row. On the textView I've called:
myTextView.setGravity(Gravity.CENTER);
And I've also tried setting it as a table parameter:
This is my XML that sets up the table:
<TableLayout
android:id="#+id/info"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/linearLayout1"
android:layout_margin="6dp"
android:stretchColumns="0,1,2,3,4" >
<TableRow
android:id="#+id/tableRow1"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:background="#drawable/roundedheader" >
And this is the code I'm calling as I create each row:
//set table margin
TableLayout.LayoutParams tableRowParams= new TableLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
int leftMargin=0,rightMargin=0,bottomMargin=0;
int topMargin=5;
tableRowParams.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);
tableRowParams.gravity = Gravity.CENTER;
row.setLayoutParams(tableRowParams);
// add the TableRow to the TableLayout
table.addView(row);
However the same command doesn't have the desired effect on the checkbox. Does any know what the difference is and what I need to do. The checkbox isn't within any other layout its just in the table row.
I recommend you before start working with TableLayout to check these links:
http://developer.android.com/reference/android/widget/TableLayout.html
http://developer.android.com/reference/android/widget/TableRow.html
http://developer.android.com/reference/android/widget/TableRow.LayoutParams.html
Also there is bunch of examples how to work with TableLayout in API Demos from Android SDK.
Assuming your layout android:stretchColumns="0,1,2,3,4" you will have at least 5 columns, but from the code snippet I can't assume how many views are added to row. You will need to specify TableRow.LayoutParams android:layout_span if there are less view elements then columns and you want to use that free space. So assuming that you have only one CheckBox in a row and only 5 columns you will need to do next:
TableRow.LayoutParams rowParams = new TableRow.LayoutParams();
rowParams.gravity = Gravity.CENTER;
rowParams.span = 5;
checkBox.setLayoutParams(rowParams);
Also I recommend you to use xml layouts instead of creating them from the code. If you can't stick with xml layouts then at least create them using xml editor, so you will have good start point for creating them from the code.
Context: I have a TableLayout (created using XML), which has one TableRow, which has one TextView. The code:
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:fillViewport="true"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TableLayout
android:id="#+id/mytable"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stretchColumns="1"
>
<TableRow>
<TextView
android:id="#+id/add_alarm"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:gravity="center"
android:text="New\nItem"
android:textSize="30sp"
/>
</TableRow>
</TableLayout>
</ScrollView>
In my Activity's onCreate() method, I am trying to add another View to the TableRow dynamically. Here is the code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutInflater inflater = LayoutInflater.from(this);
View mainLayout = inflater.inflate(R.layout.main, null);
TableLayout tl = (TableLayout) mainLayout.findViewById(R.id.mytable);
TableRow tr = (TableRow) tl.getChildAt(0);
Log.d(TAG, "tr class = " + tr.getClass().getName() + " | width = " + tr.getWidth() + "\n");
final RelativeLayout rl = (RelativeLayout) inflater.inflate(R.layout.alarm_widget, null);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1);
tr.addView(rl, lp);
tl.invalidate();
setContentView(mainLayout);
}
Question: This code is not having the intended effect of displaying both the Views (the one in the XML layout already & the other added dynamically) in a columns of equal width.
With the code given above, the dynamically added View has a width of '0' and is therefore invisible.
If I change the code to tr.addView(rl) (i.e. without reference to LayoutParams), the dynamically added view is visible, but the columns are not equal in width.
How can I achieve this?
Edit: I changed the code based on the comments to the following. It still doesn't work as expected:
TableLayout.LayoutParams lp = new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT, 1f);
tr.addView(rl, lp);
The problem is this behavior defined for TableRow:
The children of a TableRow do not need to specify the layout_width and layout_height attributes in the XML file. TableRow always enforces those values to be respectively MATCH_PARENT and WRAP_CONTENT.
Rather than add your text views directly to the TableRow, have the TableRow hold a horizontal LinearLayout and add the second view to that holder.
(Also, using LinearLayout.LayoutParams for something that's going into a TableRow is wrong. You should have been using TableRow.LayoutParams. But that wouldn't be the way to get equal-width TextViews. Use a LinearLayout holder.)
I think it's not a good idea to dynamically add an item to a TableRow - it defeats the purpose of using a table. Imagine if you add an item to the first row of the table, but not on the second, meaning the first row has more elements. It wouldn't look much like a table.
But if you insist,
From developer guide:
The children of a TableRow do not need to specify the layout_width and layout_height attributes in the XML file. TableRow always enforces those values to be respectively MATCH_PARENT and WRAP_CONTENT.
You may need to start looking on the layout_weight of each element. Try adding layout_weight=1 on the row's static elements, and then setting your dynamic RelativeLayout's weight to 1 before adding it to the row.
rl.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT, 1f));
The last parameter is weight.
Set height like this to the layout containing the ScrollView.
It solved my own problem where tablelayout does not show last lines.
android:layout_height="0dp"
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.