Creating tables – TableLayout and GridLayout

When you need to create a table in your UI, Android provides two convenient layout options: the TableLayout (along with TableRow) and the GridLayout (added in API 14). Both layout options can create similar looking tables, but each using a different approach. With the TableLayout, rows and columns are added dynamically as you build the table. With the GridLayout, row and column sizes are defined in the layout definition.

Neither layout is better, it's just a matter of using the best layout for your needs. We'll create a 3 x 3 grid using each layout to give a comparison, as you could easily find yourself using both layouts, even within the same application.

Getting ready

To stay focused on the layouts and offer an easier comparison, we will create two separate applications for this recipe. Create two new Android projects, the first called TableLayout and the other called GridLayout.

How to do it...

  1. Starting with the TableLayout project, open activity_main.xml. Change the root layout to TableLayout.
  2. Add three TableRows with three sets of TextViews to each TableRow to create a 3 x 3 matrix. For demonstration purposes, the columns are labeled A-C and the rows 1-3, so the first row of TextViews will be A1, B1, and C1. The final result will look like this:
    <TableLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="A1"
                android:id="@+id/textView1" />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="B1"
                android:id="@+id/textView2" />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="C1"
                android:id="@+id/textView3" />
        </TableRow>
        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="A2"
                android:id="@+id/textView4" />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="B2"
                android:id="@+id/textView5" />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="C2"
                android:id="@+id/textView6" />
        </TableRow>
        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="A3"
                android:id="@+id/textView7" />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="B3"
                android:id="@+id/textView8" />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="C3"
                android:id="@+id/textView9" />
        </TableRow>
    </TableLayout>
  3. Now, open the GridLayout project to edit activity_main.xml. Change the root layout to GridLayout. Add the columnCount=3 and rowCount=3 attributes to the GridLayout element.
  4. Now, add nine TextViews to GridLayout. We will use the same text as the preceding TableLayout for a consistent comparison. Since the GridView does not use TableRows, the first three TextViews are in Row 1, the next three are in Row 2, and so on. The final result will look like this:
    <GridLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:columnCount="3"
        android:rowCount="3">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="A1"
            android:id="@+id/textView1" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="B1"
            android:id="@+id/textView2" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="C1"
            android:id="@+id/textView3" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="A2"
            android:id="@+id/textView4" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="B2"
            android:id="@+id/textView5" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="C2"
            android:id="@+id/textView6" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="A3"
            android:id="@+id/textView7" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="B3"
            android:id="@+id/textView8" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="C3"
            android:id="@+id/textView9" />
    </GridLayout>
  5. You can either run the application or use the Design tab to see the results.

How it works...

As you can see when viewing the tables created, the tables basically look the same on screen. The main difference is the code to create them.

In the TableLayout XML, each row is added to the table using a TableRow. Each View becomes a column. This is not a requirement as cells can be skipped or left empty. (See how to specify the cell location in a TableRow in the following section.)

The GridLayout uses the opposite approach. The number of rows and columns are specified when creating the table. We don't have to specify the row or column information (though we can, discussed as follows). Android will automatically add each View to the cells in order.

There's more...

First, let's see more similarities between the layouts. Both layouts have the ability to stretch columns to use the remaining screen space. For the TableLayout, add the following attribute to the xml declaration:

android:stretchColumns="1"

stretchColumns specifies the (zero based) index of the columns to stretch. (android:shrinkColumns is a zero-based index of columns that can shrink, so the table can fit the screen.)

To achieve the same effect with the GridLayout, add the following attribute to all the Views in the B column (textView2, textView5, and textView8):

android:layout_columnWeight="1"
Note

All cells in a given column must define the weight or it will not stretch.

Now, let's look at some of the differences, as this is really the key to determine which layout to use for a given task. The first thing to note is how the columns and rows are actually defined. In the TableLayout, the rows are specifically defined, using a TableRow. (Android will determine the number of columns in the table based on the row with the most cells.) Use the android:layoutColumn attribute when defining the View to specify the column.

In contrast, with the GridLayout, the row and column counts are specified when defining the table (using the columnCount and rowCount as shown previously.)

In the preceding example, we just added TextViews to the GridLayout and let the system position them automatically. We can alter this behavior by specifying the row and column position when defining the View, such as:

android:layout_row="2"
android:layout_column="2"
Tip

Android automatically increments the cell counter after adding each View, so the next View should also specify the row and column, otherwise, you may not get the intended result.

Like the LinearLayout shown in the LinearLayout recipe, the GridLayout also offers the orientation attribute of supporting both horizontal (the default) and vertical. The orientation determines how the cells are placed. (Horizontal fills the columns first, then moves down to the next row. Vertical fills the first column on each row, then moves to the next column.)