How can I get an Android TableLayout to fill the parent in landscape mode?
Asked Answered
N

3

7

I am using a TableLayout in my application. It contains four TableRows each containing four ImageViews. The behavior I want is to scale the layout to fit the shortest dimension.

It works fine in portrait mode but fails miserably in landscape mode.

From the documentation it looks like this is because the TableRow layout_height is always set to WRAP_CONTENT. While I can set the dimensions of the individual Views, the TableLayout won't render at all if I set the View layout_height to FILL_PARENT.

I feel like there is something simple I am missing. Is there a way to get the TableLayout with TableRows to scale to fit the height in landscape mode?

XML Layout:

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/table"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:shrinkColumns="*">
</TableLayout>

Java:

public class Example extends Activity {

private TableLayout mTable;
private int[] mDrawableIds = {  R.drawable.draw01, R.drawable.draw02, R.drawable.draw03, R.drawable.draw04, R.drawable.draw05, R.drawable.draw06,   R.drawable.draw07, R.drawable.draw08, R.drawable.draw09, R.drawable.draw10, R.drawable.draw11, R.drawable.draw12, R.drawable.draw13, R.drawable.draw14, R.drawable.draw15, R.drawable.draw16 };

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    mTable = (TableLayout)findViewById(R.id.table);
    for (int j=0; j<4; j++) {
        TableRow tr = new TableRow(this);
        tr.setLayoutParams(new ViewGroup.LayoutParams(  LayoutParams.FILL_PARENT,
                LayoutParams.WRAP_CONTENT));
           for (int i=0; i<4; i++) {
               ImageView iv = new ImageView(this);
               iv.setImageResource(mDrawableIds[j*4+i]);
               iv.setScaleType(ImageView.ScaleType.FIT_CENTER);
               iv.setAdjustViewBounds(true);
               tr.addView(iv);
           }
        mTable.addView(tr);
    }
}
}
Neighbors answered 27/12, 2009 at 5:16 Comment(2)
Does a GridView not work for your use case? GridView tutorial here: developer.android.com/guide/tutorials/views/hello-gridview.htmlTysontyumen
GridView seems to want to scroll rather than resize the ImageViews to the landscape layout. Perhaps if I made the image resources smaller that might work. I was hoping to avoid resizing the images.Neighbors
N
4

I did figure out how to do this. Basically, the part that wasn't working the way I wanted was the TableRows. When I changed to landscape, the first two TableRows weren't resizing at all and the third was consuming the remainder of the space. The fourth row wasn't displaying at all.

I figured out that I needed to set the layout_weight of the TableRows to equal values. But, there is no method to do that at runtime, so I built the following layout file, which I called row.xml:

<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/trow"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:layout_weight="1">
</TableRow>

Then I used a LayoutInflater to build the row at runtime with the properties I wanted:

    mTable = (TableLayout)findViewById(R.id.table);
    LayoutInflater inflater = getLayoutInflater();

    for (int j=0; j<4; j++) {
        View row = inflater.inflate(R.layout.row, mTable,false);
        TableRow tr = (TableRow)row.findViewById(R.id.trow);
           for (int i=0; i<4; i++) {
               View image = inflater.inflate(R.layout.image, tr, false);
               ImageButton ib = (ImageButton)image.findViewById(R.id.image);
               ib.setAdjustViewBounds(true);
               ib.setImageResource(mCardIds[j*4+i]);
               tr.addView(ib);
           }
        mTable.addView(tr);
    }

Now the TableRows are resizing properly on rotation. I changed the ImageViews to ImageButtons because I decided to add some onClick behavior and I am building those buttons via a separate xml file, but I don't think those details are relevant to the resizing issue.

Neighbors answered 17/1, 2010 at 11:29 Comment(1)
add android:layout_weight="1" to each column in table heading row solved my problem, niceSmoot
P
4

Change your XML layout to:

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/table"
        android:layout_width="fill_parent"
        android:layout_height="160dp"
        android:shrinkColumns="*">
</TableLayout>

That should make it take up whole screen's height regardless of orientation. See density independent pixels

Pachyderm answered 29/12, 2009 at 20:54 Comment(0)
N
4

I did figure out how to do this. Basically, the part that wasn't working the way I wanted was the TableRows. When I changed to landscape, the first two TableRows weren't resizing at all and the third was consuming the remainder of the space. The fourth row wasn't displaying at all.

I figured out that I needed to set the layout_weight of the TableRows to equal values. But, there is no method to do that at runtime, so I built the following layout file, which I called row.xml:

<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/trow"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:layout_weight="1">
</TableRow>

Then I used a LayoutInflater to build the row at runtime with the properties I wanted:

    mTable = (TableLayout)findViewById(R.id.table);
    LayoutInflater inflater = getLayoutInflater();

    for (int j=0; j<4; j++) {
        View row = inflater.inflate(R.layout.row, mTable,false);
        TableRow tr = (TableRow)row.findViewById(R.id.trow);
           for (int i=0; i<4; i++) {
               View image = inflater.inflate(R.layout.image, tr, false);
               ImageButton ib = (ImageButton)image.findViewById(R.id.image);
               ib.setAdjustViewBounds(true);
               ib.setImageResource(mCardIds[j*4+i]);
               tr.addView(ib);
           }
        mTable.addView(tr);
    }

Now the TableRows are resizing properly on rotation. I changed the ImageViews to ImageButtons because I decided to add some onClick behavior and I am building those buttons via a separate xml file, but I don't think those details are relevant to the resizing issue.

Neighbors answered 17/1, 2010 at 11:29 Comment(1)
add android:layout_weight="1" to each column in table heading row solved my problem, niceSmoot
B
0

I tried the accepted solution here but it did not work. What worked is as below:

TableRow tr = new TableRow(this);
TableLayout.LayoutParams pRowTop = new TableLayout.LayoutParams(
                TableLayout.LayoutParams.MATCH_PARENT,
                TableLayout.LayoutParams.WRAP_CONTENT);
pRowTop.weight = 1;
mTable.addView(tr, pRowTop);
Bullwhip answered 22/11, 2015 at 22:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.