How can I get an Android TableLayout to fill the screen?

42,046

Solution 1

Finally worked out how to do this. Gave up on TableLayout and just used horizontal LinearLayouts inside a vertical one. The critical key is to set the weight. If you specify FILL_PARENT but with the default weight, it doesn't work:

LinearLayout buttonsView = new LinearLayout(this);
buttonsView.setOrientation(LinearLayout.VERTICAL);
for (int r = 0; r < 6; ++r)
{
    LinearLayout row = new LinearLayout(this);
    row.setOrientation(LinearLayout.HORIZONTAL);
    for (int c = 0; c < 4; ++c)
    {
        Button btn = new Button(this);
        btn.setText("A");
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT);
        lp.weight = 1.0f;
        row.addView(btn, lp);
    }
    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT);
    lp.weight = 1.0f;
    buttonsView.addView(row, lp);
}  

ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
setContentView(buttonsView, lp);

Solution 2

There are two mistakes in the above discussion.

  1. It is possible to programatically set the weight by specifying TableLayout.LayoutParams and TableRow.LayoutParams and using the appropriate constructor, e.g.

    TableLayout.LayoutParams rowInTableLp = new TableLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, 1.0f);
    
  2. A widget must have the LayoutParams of its parent. Therefore, the rows must use TableLayout.LayoutParams.

This gives you the following working version of your initial code:

TableLayout table = new TableLayout(this);
// Java. You succeed!
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
        ViewGroup.LayoutParams.FILL_PARENT,
        ViewGroup.LayoutParams.FILL_PARENT);
table.setLayoutParams(lp);
table.setStretchAllColumns(true);

TableLayout.LayoutParams rowLp = new TableLayout.LayoutParams(
        ViewGroup.LayoutParams.FILL_PARENT,
        ViewGroup.LayoutParams.FILL_PARENT,
        1.0f);
TableRow.LayoutParams cellLp = new TableRow.LayoutParams(
        ViewGroup.LayoutParams.FILL_PARENT,
        ViewGroup.LayoutParams.FILL_PARENT,
        1.0f);
for (int r = 0; r < 2; ++r)
{
    TableRow row = new TableRow(this);
    for (int c = 0; c < 2; ++c)
    {
        Button btn = new Button(this);
        btn.setText("A");
        row.addView(btn, cellLp);
    }
    table.addView(row, rowLp);
}
setContentView(table);

Thanks to Romain Guy's comment on Android developer's forum for the solution.

Solution 3

Found the answer: apparently it is the layout_weight that makes it work and there is no way to set it from Java. Damnit.

See How can I get an Android TableLayout to fill the parent in landscape mode?

Share:
42,046
Timmmm
Author by

Timmmm

Updated on August 09, 2020

Comments

  • Timmmm
    Timmmm over 3 years

    I'm battling with Android's awful layout system. I'm trying to get a table to fill the screen (simple right?) but it's ridiculously hard.

    I got it to work somehow in XML like this:

    <?xml version="1.0" encoding="utf-8"?>
    
    <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:layout_width="fill_parent">
    <TableRow android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="1">
    <Button android:text="A" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_weight="1"/>
    <Button android:text="B" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_weight="1"/>
    </TableRow>
    <TableRow android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="1">
    <Button android:text="C" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_weight="1"/>
    <Button android:text="D" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_weight="1"/>
    </TableRow>
    

    However I can not get it to work in Java. I've tried a million combinations of the LayoutParams, but nothing ever works. This is the best result I have which only fills the width of the screen, not the height:

        table = new TableLayout(this);
        // Java. You suck.
        TableLayout.LayoutParams lp = new TableLayout.LayoutParams(
                                        ViewGroup.LayoutParams.FILL_PARENT,
                                        ViewGroup.LayoutParams.FILL_PARENT);
        table.setLayoutParams(lp); // This line has no effect! WHYYYY?!
        table.setStretchAllColumns(true);
        for (int r = 0; r < 2; ++r)
        {
            TableRow row = new TableRow(this);
            for (int c = 0; c < 2; ++c)
            {
                Button btn = new Button(this);
                btn.setText("A");
                row.addView(btn);
            }
            table.addView(row);
        }
    

    Obviously the Android documentation is no help. Anyone have any ideas?