28

I'm trying to create a TableLayout programatically. It just won't work. The same layout in an xml file works though. This is what I have:

public class MyTable extends TableLayout
{
    public MyTable(Context context) {
        super(context);

        setLayoutParams(new TableLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
        TableRow row = new TableRow(context);
        row.setLayoutParams(new TableRow.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));

        Button b = new Button(getContext());
        b.setText("hello");
        b.setLayoutParams(new LayoutParams(TableRow.LayoutParams.FILL_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
        row.addView(b); 
        addView(row)
    }
}

...

// In main activity:
MyTable table = new MyTable(this);
mainLayout.addView(table);

When I run this, I don't get a crash, but nothing appears. If I get rid of the TableRow instance, at least the button does appear as a direct child of the TableLayout. What am I doing wrong?

Cœur
  • 37,241
  • 25
  • 195
  • 267
mark
  • 1,697
  • 3
  • 14
  • 13

5 Answers5

42

Just to make the answer more clear:

TableLayout.LayoutParams tableParams = new TableLayout.LayoutParams(TableLayout.LayoutParams.WRAP_CONTENT, TableLayout.LayoutParams.WRAP_CONTENT);
TableRow.LayoutParams rowParams = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT);

TableLayout tableLayout = new TableLayout(context);
tableLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));// assuming the parent view is a LinearLayout

TableRow tableRow = new TableRow(context);
tableRow.setLayoutParams(tableParams);// TableLayout is the parent view

TextView textView = new TextView(context);
textView.setLayoutParams(rowParams);// TableRow is the parent view

tableRow.addView(textView);

Explanation
When you call setLayoutParams, you are supposed to pass the LayoutParams of the parent view

ericn
  • 12,476
  • 16
  • 84
  • 127
Grigori A.
  • 2,628
  • 1
  • 21
  • 19
  • 4
    Shouldn't it be tableRow.setLayoutParams(rowParams) ? – Leon Nov 09 '15 at 11:18
  • The life saver award goes to @Gigori A. and mark. Gigori A. for this answer and mark for his own answer. – Muneeb Mirza May 14 '16 at 10:48
  • Great and helpful solution. As a side note, you should add the row to the table before you add the textview to the row. tableLayout.addView(tableRow); – The_Martian Oct 20 '16 at 03:58
  • 3
    Spent an hour trying to figure out what I was doing wrong - turns out in your code you missed adding `tableRow` to the `tableLayout`: `tableLayout.addView(tableRow);` – Starwave May 08 '17 at 09:37
  • @The_Martian. actually, that's not mandatory. it also works first filling the row and then adding the latter to the table. In my strict opinion, that is more intuitive. – albaspazio May 24 '22 at 09:13
6

It turns out I needed to specify TableRowLayout, TableLayout etc for the layout params, otherwise the table just won't show!

mark
  • 1,697
  • 3
  • 14
  • 13
  • 2
    Can you post your code solution? It looks like you are already doing that above. – Atma Aug 29 '11 at 21:19
  • 4
    Thank you! @Atma TableRows should use TableLayout.LayoutParams and views inside the TableRows should use TableRow.LayoutParams. :) – Brayden May 15 '12 at 15:03
  • Horrible that you need to explicitly do this, but it worked for me, thanks! – Geert Weening Mar 18 '13 at 19:01
  • Thank you @Brayden! That was the small detail I missed in my subclass of TableLayout that automatically had all TableLayout.LayoutParams and not TableRow.LayoutParams! – Anonsage Oct 08 '14 at 18:02
1

For me, to get mine I had to call addContentView().

Korhan Ozturk
  • 11,148
  • 6
  • 36
  • 49
John Moses
  • 1,283
  • 1
  • 12
  • 18
1

A good solution is to inflate layout files for each instance of row you want to create. See this post : How to duplicate Views to populate lists and tables?

Community
  • 1
  • 1
clotilde
  • 31
  • 3
0

Your problem is at this line:

b.setLayoutParams(new LayoutParams(TableRow.LayoutParams.FILL_PARENT, TableRow.LayoutParams.WRAP_CONTENT));

You need to change LayoutParams to TableRow.LayoutParams:

b.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
ericn
  • 12,476
  • 16
  • 84
  • 127