Question

The table I'm looking for has a number of rows, each of which has several columns which need to have their size automatically generated so that they display at the maximum width required to display them, and one of which needs to expand/contract to fill the remaining space.

I've tried to accomplish this by flagging the expanding/contracting column as shrinkable and stretchable. But this doesn't seem to work - when the table is wider than the available space, the column is not being shrunk, and instead the table is cut off on the right hand side, with several columns not visible.

Any pointers as to where I could be going wrong with this?

Was it helpful?

Solution 2

You can try using the layout weight for the cells. Something like shown below

private static int COLUMN_WEIGHT_1 = 3;
private static int COLUMN_WEIGHT_2 = 1;
private static int COLUMN_WEIGHT_3 = 2;

// this column will stretch to fill the space
private static int COLUMN_WEIGHT_4 = 0;

private void populatePriceTable(){
    TableLayout prices = (TableLayout)findViewById(R.id.pricetable);
    prices.setStretchAllColumns(true);
    prices.bringToFront();

    TableRow tr =  new TableRow(this);
    TextView c1 = new TextView(this);
    c1.setText("A cell");
    TextView c2 = new TextView(this);
    c2.setText("A large cell");
    c2.setGravity(Gravity.CENTER_HORIZONTAL);
    TextView c3 = new TextView(this);
    c3.setText("Another large cell");
    TextView c4 = new TextView(this);
    c4.setGravity(Gravity.RIGHT);
    c4.setText("Filler");
    c1.setLayoutParams( new TableRow.LayoutParams( 0 , android.view.ViewGroup.LayoutParams.WRAP_CONTENT, COLUMN_WEIGHT_1) );
    c2.setLayoutParams( new TableRow.LayoutParams( 0 , android.view.ViewGroup.LayoutParams.WRAP_CONTENT, COLUMN_WEIGHT_2) );
    c3.setLayoutParams( new TableRow.LayoutParams( 0 , android.view.ViewGroup.LayoutParams.WRAP_CONTENT, COLUMN_WEIGHT_3) );
    c4.setLayoutParams( new TableRow.LayoutParams( 0 , android.view.ViewGroup.LayoutParams.WRAP_CONTENT, COLUMN_WEIGHT_4) );
    tr.addView(c1);
    tr.addView(c2);
    tr.addView(c3);
    tr.addView(c4);
    tr.setLayoutParams(new TableRow.LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT));
    prices.addView(tr);     
}

OTHER TIPS

Recently I had to face a similar requirement for an app and I finally could get it working. In my case I needed to create one TableLayout and add TableRows dynamically depending on the screen's width. The Views added to the TableRow were TextViews with the layout_weight property set, so I had to play around with the number of items shown per row, and finally could tune up the desired layout.

I'll paste my code and explain what I'm doing at each step:

// The following code block is to dynamically get the width of the screen.
// The width param will be reachable within the `params.width` property    

final Display display = getWindowManager().getDefaultDisplay();
final Point size = new Point();
display.getSize(size);

final WindowManager.LayoutParams params = getWindow().getAttributes();

// So now I have to take the TableLayout and add TableRows dynamically. I'll be adding
// TextViews to the row with the texts present at myItems

TableLayout myTableLayout = (TableLayout) findViewById(R.id.table_layout);
TableRow currentRow = new TableRow(this);
int currentWidth = 0;

for (final String item : myItems) {
  // Define the TextView
  final TextView tv = new TextView(this);
  tv.setBackground(getResources().getDrawable(R.drawable.rounded_edges));
  tv.setGravity(Gravity.CENTER);
  tv.setText(item);
  ...

  // This one line is very important, as you're defining the layout params.
  // Make sure that you add the 1f parameter as it represents the weight
  // Each TextView will have the same weight so they will have the same width
  // within the row
  tv.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT, 1f));

  ...

  // Now you check if this cell still fits the TableRow
  // I use the 90% because the TableLayout won't ever be 100% of the screen width
  if (currentWidth + tv.getWidth() < ((int) params.width * 0.9)) {
    // It fits!
    currentRow.addView(tv);
    currentWidth = currentWidth + tv.getWidth();
  }
  else {
    // It doesn't fit. Just add the current row to the TableLayout and go on.
    myTableLayout.add(currentRow);
    currentRow = new TableRow(this);
    currentRow.addView(tv);
    currentWidth = tv.getWidth();
  }
}

// It might happen that once I've ended processing the texts, there's still
// a row pending to add, so if it has any child I add it
if (currentRow.getChildCount() > 0)
  myTableLayout.add(currentRow);

You can just have a ListView and have a seperate xml layout file which is actually a Table layout.

so as in listview you can handle as much rows you want and table layout will make it elastic.

Write Seperate XML layout for row like this....and use wrap content/fill parent attribute according to text size

  <?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginBottom="3dp"
    android:layout_marginTop="3dp"
    android:background="#FFFFFF" 
    android:id="@+id/row_calender">



        <TextView
            android:id="@+id/tv_ac_sn"
            android:layout_width="35dp"
            android:layout_height="fill_parent"
            android:background="@drawable/border"
            android:gravity="center"
            android:padding="5dp"
            android:textColor="#000000" />

        <TextView
            android:id="@+id/tv_ac_day"
            android:layout_width="85dp"
            android:layout_height="fill_parent"
            android:background="@drawable/border"
            android:gravity="center"
            android:padding="5dp"
            android:textColor="#000000" />

        <TextView
            android:id="@+id/tv_ac_date"
            android:layout_width="85dp"
            android:layout_height="fill_parent"
            android:background="@drawable/border"
            android:gravity="center"
            android:padding="5dp"
            android:textColor="#000000" />

        <TextView
            android:id="@+id/tv_ac_event"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="@drawable/border"
            android:gravity="center"
            android:padding="5dp"`
            android:textColor="#000000" />
    </TableRow>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top