141

I'm using a TableLayout in Android. Right now I have one TableRow with two items in it, and, below that, a TableRow with one item it it. It renders like this:

-----------------------------
|   Cell 1    |  Cell 2     |
-----------------------------
|   Cell 3    |
---------------

What I want to do is make Cell 3 stretch across both upper cells, so it looks like this:

-----------------------------
|   Cell 1    |  Cell 2     |
-----------------------------
|           Cell 3          |
-----------------------------

In HTML I'd use a COLSPAN.... how do I make this work in Android?

Jonik
  • 80,077
  • 70
  • 264
  • 372
Spike Williams
  • 35,795
  • 13
  • 48
  • 60
  • Imho, I fount better way to do this. Here the answer: http://stackoverflow.com/a/18682293/1979882 – Vyacheslav Sep 08 '13 at 09:39
  • 1
    For the record, notice that a TableLayout is essentially a LinearLayout. That means that you can add any child directly. So for a single all-column-span view, you could skip the TableRow. – ralfoide Feb 02 '15 at 22:47

9 Answers9

207

It seems that there is an attribute doing that : layout_span

UPDATE: This attribute must be applied to the children of the TableRow. NOT to the TableRow itself.

catalyst294
  • 129
  • 9
Sephy
  • 50,022
  • 30
  • 123
  • 131
  • 8
    Yup, this is the one. The Eclipse layout widget doesn't seem to know about it, however, as it was not listed among the available properties. But it does work. – Spike Williams Apr 26 '10 at 13:30
  • 2
    You know, +1 for your update in the answer. I was trying to find out why is Eclipse not giving that option on Ctrl+Space! :D ;) – Nirav Zaveri Nov 28 '14 at 13:20
  • I i use layout_span on my view. Then i can't use weight on that view. I have to use wrap_content. Why? – eC Droid Jul 31 '17 at 14:07
97

Just to complete the answer, the layout_span attribute must be added to the child, not to TableRow.

This snippet shows the third row of my tableLayout, which spans for 2 columns.

<TableLayout>
    <TableRow
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_span="2"
            android:text="@string/create" />
    </TableRow>
</TableLayout>
Maragues
  • 37,861
  • 14
  • 95
  • 96
42

And this is how you do it programmatically

//theChild in this case is the child of TableRow
TableRow.LayoutParams params = (TableRow.LayoutParams) theChild.getLayoutParams();
params.span = 2; //amount of columns you will span
theChild.setLayoutParams(params);
Onimusha
  • 3,348
  • 2
  • 26
  • 32
  • 7
    You may also need to set params.weight = 1 to make the spanned content fill the row. – rmirabelle Aug 20 '13 at 20:51
  • 1
    It doesn't work. http://stackoverflow.com/a/18682293/1979882 Here I wrote the explaination. – Vyacheslav Sep 08 '13 at 09:38
  • 7
    Make sure to add the child to the row first. – Artem Kalinchuk Apr 21 '14 at 10:35
  • 1
    @DacSaunders Answer rolled back. Your edit was specific to your need. The original answer is generic for the method and 31 thumbs up might tell you maybe you're doing something wrong? See Artem's comment also that highlights the child needs to be added first. The `child` in this case can be anything, not just textview as your edit suggested. Thanks – Onimusha Nov 25 '17 at 15:23
30

You have to use layout_weight to fill the entire row otherwise it still fills left or right column of table layout.

<TableRow
  android:id="@+id/tableRow1"
  android:layout_width="match_parent"
  android:layout_height="wrap_content">

        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_span="2"
            android:layout_weight="1"
            android:text="ClickMe" />

    </TableRow>
Raghavendra
  • 2,305
  • 25
  • 30
  • 3
    Thank you. This was the missing information for small or flexible elements, in my case a Spinner. – chksr Feb 07 '16 at 08:25
  • 1
    This is an essential addition to the [currently accepted answer](https://stackoverflow.com/a/2713323/8387076) by @Sephy. – Wrichik Basu Nov 09 '22 at 15:28
5

Maybe this will help someone. I tried the solution with layout_span but this not working for me. So I solved the problem with this trick. Just use LinearLayout in place of TableRow where you need colspan, that's all.

Dimanoid
  • 6,999
  • 4
  • 40
  • 55
3

use android:layout_span in child element of TableRow element

Mosiur
  • 1,342
  • 13
  • 16
1

I've had some problem with rowspan, in case of TableRow, Textview and so on, generated with code. Even if Onimush answer seems to be good, it don't works with generated UI.

Here is a piece of code which.... don't work:

            TableRow the_ligne_unidade = new TableRow(this);
            the_ligne_unidade.setBackgroundColor(the_grey);

            TextView my_unidade = new TextView(this);
            my_unidade.setText(tsap_unidade_nom);
            my_unidade.setTextSize(20);
            my_unidade.setTypeface(null, Typeface.BOLD);
            my_unidade.setVisibility(View.VISIBLE);

            TableRow.LayoutParams the_param;
            the_param = (TableRow.LayoutParams)my_unidade.getLayoutParams();
            the_param.span = 3;
            my_unidade.setLayoutParams(the_param);

            // Put the TextView in the TableRow
            the_ligne_unidade.addView(my_unidade);

The code seems to be OK but, when you reach the init of "the_params" it returns NULL.

On the other end, this code works like a charm:

            TableRow the_ligne_unidade = new TableRow(this);
            the_ligne_unidade.setBackgroundColor(the_grey);

            TextView my_unidade = new TextView(this);
            my_unidade.setText(tsap_unidade_nom);
            my_unidade.setTextSize(20);
            my_unidade.setTypeface(null, Typeface.BOLD);
            my_unidade.setVisibility(View.VISIBLE);

            // Put the TextView in the TableRow
            the_ligne_unidade.addView(my_unidade);

            // And now, we change the SPAN
            TableRow.LayoutParams the_param;
            the_param = (TableRow.LayoutParams)my_unidade.getLayoutParams();
            the_param.span = 3;
            my_unidade.setLayoutParams(the_param);

The only difference is that I push the Textview inside the TableRow before setting the span. And in this case, it works. Hope this will help someone!

Peter
  • 1,247
  • 19
  • 33
1

Actually It is pretty straight forward. This is my solution programmatically

        TableLayout tableLayout = binding.tableLayout;
        TableRow row = new TableRow(this);
        TableRow.LayoutParams layoutParams = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT);
        layoutParams.span = 4;               // define no. of column span will row do
        row.setLayoutParams(layoutParams);

        TextView noDataTextView = new TextView(this);
        noDataTextView.setText("No Data");
        noDataTextView.setGravity(Gravity.CENTER);
        noDataTextView.setLayoutParams(layoutParams);   //This line will span your row

        row.addView(noDataTextView);
        tableLayout.addView(row, 1);
0

I think you need to wrap a layout around another one. Have one Layout list vertically, inside have another one (or in this case, two) list horizontally.

I'm still finding it hard to nicely split interface to 50-50 portion in Android.

RobGThai
  • 5,937
  • 8
  • 41
  • 59
  • I ended up doing this to get around a different table-related bug that was causing 1/3 of my layout to be hidden in landscape mode, for unknown reasons. – Spike Williams Apr 27 '10 at 04:06