Search code examples
androidandroid-gridlayout

Dynamic GridLayout with evenly spaced controls


We need to place arbitrary controls in a Grid, supporting colspan (and probably further down the road rowspan, too). So I was looking at Android's GridLayout, as it seems to just support that. I've set up a minimal example just placing TextViews in some cells.

My XML looks like this:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#cccccc"
    android:orientation="horizontal"
    android:weightSum="1"
    android:id="@+id/root">
    <GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent" android:layout_height="wrap_content"
        android:background="@android:color/holo_green_dark" android:layout_weight="1">
        <TextView android:text="Erstes" android:layout_row="0" android:layout_column="0" android:layout_columnSpan="2" android:layout_columnWeight="1"  android:background="#333333" />
        <TextView android:text="Zweites" android:layout_row="1" android:layout_column="2" android:layout_columnWeight="1"  android:background="#666666" />
        <TextView android:text="Drittes" android:layout_row="1" android:layout_column="1" android:layout_columnWeight="1"  android:background="#888888"/>
        <TextView android:text="Viertes" android:layout_row="2" android:layout_column="3" android:layout_columnWeight="1"  android:background="#aaaaaa" />
        <Space android:layout_row="1" android:layout_column="0" android:layout_width="10dp" android:layout_columnWeight="1" android:layout_gravity="fill_horizontal" />
    </GridLayout>
</LinearLayout>

Had to put in the Space with a fixed width in there to not have the first cell in the second row collapse. My first question would be, if there is another way to do this? As I would like to avoid setting the width of anything as the number of columns and corresponding site of each cell isn't really known beforehand. (Edit: I guess you can disregard the android:layout_gravity="fill_horizontal" part of that. That was just me trying around.)

Also with that XML (or by doing the same in code) I end up with unevenly spaced columns in the final result. It appears that columns containing cells with wider content (text) in them are given more space overall. How can I avoid this?

You can see the result on the picture below, although it might be barely noticeable at first glance. Best noticeable for the cell only containing the 10dp-wide Space view. enter image description here

Am I expecting too much of GridLayout here? Thanks for any help!


Solution

  • For your first question, the obvious answer might be to add Space view wherever the controls are missing and set all the views to have equal weight.

    And for the second issue, it would be good to set the layout_width to 0dp as they're set to wrap_content by default.

    Ignore the following as you're already using API 21.

    The Support Library has a better GridLayout. It lets you specify weights for each view, which means you can evenly distribute space by letting each of them have equal weight.

    To be more specific, add compile "com.android.support:gridlayout-v7:${SUPPORT_LIBRARY}" to your list of Gradle dependencies, where ${SUPPORT_LIBRARY} is the latest version available.

    And use android.support.v7.widget.GridLayout tag for the layout.