2011-01-22

Fixed header in a TableLayout

As the previous post this will also cover TableLayout. As with borders, there are no attribute for defining a TableRow as a header row. With header row I mean a row that will not scroll with the rest of the data in the TableLayout (providing you have declared the table to be inside a ScrollView).

Well, there is actually a way to work around this using a separate TableLayout for the header row. If you know that the header columns will be wider than the rest of the data in the table it's pretty easy. Some key notes to make this work:


  • Set all Views in the table to android:layout_weight="1"
  • You must NOT set android:stretchColumns="*" as this will override the weight attribute.
  • You must know which row is widest, and use a copy of this as a "dummy" row.
In the layout xml add the header row:
<TableLayout
  android:id="@+id/header"
  android:layout_width="fill_parent"
  android:layout_marginRight="2dp"
  android:layout_marginLeft="2dp"
  android:layout_height="wrap_content"
  android:background="@android:color/black">
  <TableRow>
   <TextView
    android:textColor="@android:color/black"
    android:layout_margin="1dp"
    android:gravity="center_horizontal"
    android:layout_weight="1"
    android:background="#ffcccccc"
    android:text="Col1" />
   <TextView
    android:textColor="@android:color/black"
    android:gravity="center_horizontal"
    android:layout_weight="1"
    android:layout_margin="1dp"
    android:background="@android:color/white"
    android:text="Col2" />
   <TextView
    android:textColor="@android:color/black"
    android:gravity="center_horizontal"
    android:layout_weight="1"
    android:layout_margin="1dp"
    android:background="@android:color/white"
    android:text="Col3" />
   <TextView
    android:textColor="@android:color/black"
    android:gravity="center_horizontal"
    android:layout_weight="1"
    android:layout_margin="1dp"
    android:background="@android:color/white"
    android:text="Col4" />
   <TextView
    android:textColor="@android:color/black"
    android:gravity="center_horizontal"
    android:layout_weight="1"
    android:layout_margin="1dp"
    android:background="@android:color/white"
    android:text="Col5" />
  </TableRow>
 </TableLayout>
Then add the main table inside a ScrollView containing a copy of the header row as a dummy row with a height set to "0dp" making it invisible:
<ScrollView
  android:id="@+id/table_scroll"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:layout_marginRight="2dp"
  android:layout_marginLeft="2dp">
  <TableLayout
   android:id="@+id/maintable"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:background="@android:color/black">
   <TableRow>
    <TextView
     android:layout_height="0dp"
     android:layout_weight="1"
     android:layout_marginRight="1dp"
     android:layout_marginLeft="1dp"
     android:text="Col1" />
    <TextView
     android:layout_height="0dp"
     android:layout_weight="1"
     android:layout_marginLeft="1dp"
     android:layout_marginRight="1dp"
     android:text="Col2" />
    <TextView
     android:layout_height="0dp"
     android:layout_weight="1"
     android:layout_marginLeft="1dp"
     android:layout_marginRight="1dp"
     android:text="Col3" />
    <TextView
     android:layout_height="0dp"
     android:layout_weight="1"
     android:layout_marginLeft="1dp"
     android:layout_marginRight="1dp"
     android:text="Col4" />
    <TextView
     android:layout_height="0dp"
     android:layout_weight="1"
     android:layout_marginLeft="1dp"
     android:layout_marginRight="1dp"
     android:text="Col5" />
   </TableRow>
  </TableLayout>
 </ScrollView>
This is how it is displayed:


Note that this will only work if you know that the header columns is wider than the rest of the data. If any of the rows in the "main" table is wider than the header row the columns will no longer be aligned. However, there is a way to solve this as well. If you can identify the widest row in the "main" table, then just do the same procedure as above, but this time add this as a dummy row to the header table.

9 kommentarer:

  1. thank you for this great adventure into the world of android sir!

    SvaraRadera
  2. Thanks. very nice. I have a question sir, How to display Col1 constantly on the screen even when the table is scrolled horizontally?

    SvaraRadera
    Svar
    1. How to display Col1 constantly on the screen even when the table is scrolled horizontally?
      can u share the code

      Radera
  3. You can also put, on each textview, a width of "0dp" and a weight of "0.20" (in your case).
    This will keep all the columns at the same width, whatever the text you put in your textviews (header or not).

    SvaraRadera
  4. I can't set the row height to 0 programatically. The following results in normal height, not 0 height:
    TableRow.LayoutParams flatRowParams = new TableRow.LayoutParams();
    flatRowParams.height = 0; // extreme flatness
    flatRowParams.width = LayoutParams.WRAP_CONTENT;
    itemTable.addView(rowItem, flatRowParams)

    SvaraRadera
  5. Success... I was able to set the height of each item in a row to 0 and that flattened the row. Here is the XML I used, it supports horizontal and vertical scrolling.
















    SvaraRadera