Just like HTML Tables on webpages the TableLayout on Android gives you the option to align Views in a table order with rows and columns.
My development setup is:
IDE: Eclipse IDE (setup guide here).
Phone: HTC Hero
Android version: 1.5 HTC Rom
I will be using the standard Android Project Skeleton in Eclipse as my base setup. This auto creates all the basic files needed, so these will not be covered here.
TableLayout on Android
The TableLayout is built using the TableLayout and the TableRow commands. There is no TableCols like the <td> tag in HTML. To align your view in columns you have to set the width of the elements and manually control the layout.
XML Layout
To make a basic layout with 2 rows and 4 textview I have a main.xml with this content:
<TableLayout android:id="@+id/TableLayout01" android:layout_width="wrap_content" android:layout_height="wrap_content">
<TableRow android:id="@+id/TableRow01" android:layout_width="wrap_content" android:layout_height="wrap_content">
<TextView android:id="@+id/TextView01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="textfield 1-1"></TextView>
<TextView android:id="@+id/TextView02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="textfield 1-2"></TextView>
</TableRow>
<TableRow android:id="@+id/TableRow02" android:layout_width="wrap_content" android:layout_height="wrap_content">
<TextView android:id="@+id/TextView03" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="textfield 2-1"></TextView>
<TextView android:id="@+id/TextView04" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="textfield 2-2"></TextView>
</TableRow>
</TableLayout>
This creates a layout like this:

So we have now displayed a simple TableLayout.
Right aligning checkboxes
Many apps have a nice clean setup where the checkboxes is right aligned to the screen and this is actually very easy to achieve. You just have to set the width of the textview so it will push the checkbox to the right.
First step is to change the TextView02 to a Checkbox like this:
...
<TextView android:id="@+id/TextView01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="textfield 1-1"></TextView>
<CheckBox android:id="@+id/CheckBox01" android:layout_width="wrap_content" android:layout_height="wrap_content"></CheckBox>
This will output somethings like this:

Now we just have to align the checkbox.
We can do this by setting the width of the previous textfield like this:
<TableRow android:id="@+id/TableRow01" android:layout_width="wrap_content" android:layout_height="wrap_content"><TextView android:id="@+id/TextView01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="textfield 1-1" android:width="250px"></TextView>
Notice the width=”250px” in the end there. This results in:

But what is the screen size changes? The checkbox will then be placed 250px from the left because the width is hardcoded. Not that great – but yet very easy to adjust.
On the LayoutTable we can adjust stretching across columns, similar to the colspan tag in HTML.
... <TableLayout android:id="@+id/TableLayout01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:stretchColumns="0"> ...
This will make the first (“0″) column stretch as most as needed and allowed by the other elements.:

And with the screen flipped:

Complete XML layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TableLayout android:id="@+id/TableLayout01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:stretchColumns="0">
<TableRow android:id="@+id/TableRow01" android:layout_width="wrap_content" android:layout_height="wrap_content">
<TextView android:id="@+id/TextView01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="textfield 1-1"></TextView>
<CheckBox android:id="@+id/CheckBox01" android:layout_width="wrap_content" android:layout_height="wrap_content"></CheckBox>
</TableRow>
<TableRow android:id="@+id/TableRow02" android:layout_width="wrap_content" android:layout_height="wrap_content">
<TextView android:id="@+id/TextView03" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="textfield 2-1"></TextView>
<TextView android:id="@+id/TextView04" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="textfield 2-2"></TextView>
</TableRow>
</TableLayout>
</LinearLayout>
Appending rows dynamically
Lets say you want to add rows to the TableLayout on depend during your app. No problem.
Add a button at the top of your application like this:
<Button android:id="@+id/Button01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Add row"></Button>
<ScrollView android:id="@+id/ScrollView01" android:layout_width="wrap_content" android:layout_height="wrap_content">
<TableLayout android:id="@+id/TableLayout01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:stretchColumns="0">
<TableRow android:id="@+id/TableRow01" android:layout_width="wrap_content" android:layout_height="wrap_content">
<TextView android:id="@+id/TextView01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="textfield 1-1"></TextView>
<CheckBox android:id="@+id/CheckBox01" android:layout_width="wrap_content" android:layout_height="wrap_content"></CheckBox>
</TableRow>
</TableLayout>
</ScrollView>
There is now a button available for handling clicks from the user and the TableLayout has been wrapped in a ScrollView which enables the scroll functionality.
Now for some Java code
package huuah.tablelayout;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TableLayout;
import android.widget.TextView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TableRow;
import android.widget.TableRow.LayoutParams;
public class tablelayout extends Activity implements OnClickListener {
/** Called when the activity is first created. */
//initialize a button and a counter
Button btn;
int counter = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setup the layout
setContentView(R.layout.main);
// add a click-listener on the button
btn = (Button) findViewById(R.id.Button01);
btn.setOnClickListener(this);
}
// run when the button is clicked
public void onClick(View view) {
// get a reference for the TableLayout
TableLayout table = (TableLayout) findViewById(R.id.TableLayout01);
// create a new TableRow
TableRow row = new TableRow(this);
// count the counter up by one
counter++;
// create a new TextView
TextView t = new TextView(this);
// set the text to "text xx"
t.setText("text " + counter);
// create a CheckBox
CheckBox c = new CheckBox(this);
// add the TextView and the CheckBox to the new TableRow
row.addView(t);
row.addView(c);
// add the TableRow to the TableLayout
table.addView(row,new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
}

So whenever the button is clicked, it adds a new row to the TableLayout and notice the Scrollbar from the ScrollView.
If you want more information and TableLayout and placement techniques I can recommend reading:

Thats it for now. Enjoy coding and please post some comments.

juni 8th, 2010 at 00:07
Hey,
Thanks a ton for the posting. I was searching all the sites for this particular lay out..
juni 20th, 2010 at 21:22
hi,
I want to add the row at a particular position. Right now it is adding at the end of the table. Is there a way that I can mention after what id i want rows to be added.
Thanks,
Prerna
juni 20th, 2010 at 21:57
According to the Android API it should be possible to add a position index with the addView() – addView documentation.
Try something like:
table.addView(row, position, new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
august 11th, 2010 at 02:16
i was wondering if it was possible to extract the TableRow resource definition to it’s own main_row.xml and change onClick so that instead of creating a row by hand it uses that resource file to build the row accordingly, i.e.
LayoutInflater inflater = (LayoutInflater) this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.main_row, null);
TableLayout table = (TableLayout) findViewById(R.id.TableLayout01);
TableRow row = new TableRow(this);
row.addView(rowView.findViewById(R.id.TableRow01));
table.addView(row);
this seems to work, but the android:stretchColumns definition from the tableLayout appears to be disregarded in that case and i don’t understand why
august 23rd, 2010 at 01:35
When the text is too long, the checkbox is pushed “outside” of the screen.
I want to let the checkbox at right of the screen, even when text is long.
How can I do to limit the label space when the text is long?
The text would be cut and scroll when its row is active.
Thanks,
Geo
oktober 26th, 2010 at 05:45
I’ve got a major issue: how to remove the dynamically appended table?
oktober 30th, 2010 at 13:24
#6 Ariga:
I have recently upgraded my computer and I have not yet installed Eclipse and the Android environment. I can therefor not answer your question at this time, but I will return as soon as I have my setup up and running again.
januar 18th, 2011 at 08:09
How I can create and use TableLayout with more than 1 columns?
Please Help me>>>
januar 21st, 2011 at 12:12
Hi, ever tried placing a progressbar while adding table rows?
januar 27th, 2011 at 18:19
I have the same problem as @Geo, when the text is too long the checkbox is pushed “outside” of the screen. Any ideas?
januar 28th, 2011 at 19:47
I want to be able to click on the first row of my table to bring up a dialog how would I do this with an OnClickListener ?
maj 6th, 2011 at 09:07
Hey androidian, thanks a lot for posting such a greate article. It helped me a lot. Keep posting helpful things for android beginners like me.
regards,
sathish
juni 20th, 2011 at 13:51
Hi,
I want to put more than one progress bar in an android activity for loading different images when i click on particular image which is retrieving from web. So can you help me to implement progress-bar.
Thanks,
Murali.
juli 7th, 2011 at 22:33
I know I’m late at responding to this article but I have the same problem as described in #5 and #10. Have anyone of you got a solution to the problem?
juli 7th, 2011 at 23:00
I can answer my own question since I finally managed to solve the problem myself. Add the attribute:
android:shrinkColumns
to the TableLayout definition. It’ll shrink to fit the parent width. More info is available here:
http://developer.android.com/reference/android/widget/TableLayout.html
and in detail in the specific attribute section
http://developer.android.com/reference/android/widget/TableLayout.html#attr_android:shrinkColumns
februar 15th, 2012 at 17:12
Hi, and thanks for the great article.
Could you tell me how to prevent newly widgets passing away upon rotating the device? I mean, when I’ve stuffed some table lines with components, rotating the device shows me the initial screen, all previous work vanishes. And, second, how would you manage the listeners on dynamically added components in table rows so that there will be one listener object that decides what row the component belongs to?
Thank you for your replies.
maj 25th, 2012 at 06:49
Hi, this article is great! Thankyou for posting!
I have this question, when you say (this) when creating TableRow and TextView, what are you refering to? I got confused.
Again, this is very helpful. Thank you very much for posting
juli 9th, 2012 at 15:27
Hi,
This is a very good explanation working with table layout in android.
februar 28th, 2013 at 18:28
A very helpful article … especially the part with appending rows to the table dynamically. Thanks for posting!