androidandroid-layoutandroid-gridviewandroid-gridlayout

GridLayout (not GridView) how to stretch all children evenly


I want to have a 2x2 grid with a buttons inside. This is only ICS so I am trying to use the new GridLayout given.

Here's the XML of my layout:

 <?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/favorites_grid"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#00ff00"
    android:rowCount="2"
    android:columnCount="2">
  <Button
      android:text="Cell 0"
      android:layout_row="0"
      android:layout_column="0"
      android:textSize="14dip" />
  <Button
      android:text="Cell 1"
      android:layout_row="0"
      android:layout_column="1"
      android:textSize="14dip" />

  <Button
      android:text="Cell 2"
      android:layout_row="1"
      android:layout_column="0"
      android:textSize="14dip" />
  <Button
      android:text="Cell 3"
      android:layout_row="1"
      android:layout_column="1"
      android:textSize="14dip" />
</GridLayout>

The problem is that my views do not stretch evenly for each row. This causes a lot of extra space to the right of my GridLayout.

I tried setting layout_gravity="fill_horizontal" but that only applies to the last view on the row. This means Cell 1 stretches all the way to give enough space for Cell 0.

Thoughts on how to tackle this?


Solution

  • UPDATE: Weights are supported as of API 21. See PaulT's answer for more details.

    There are limitations when using the GridLayout, the following quote is taken from the documentation.

    "GridLayout does not provide support for the principle of weight, as defined in weight. In general, it is not therefore possible to configure a GridLayout to distribute excess space in non-trivial proportions between multiple rows or columns ... For complete control over excess space distribution in a row or column; use a LinearLayout subview to hold the components in the associated cell group."

    Here is a small example that uses LinearLayout subviews. (I used Space Views that takes up unused area and pushes the buttons into desired position.)

    <GridLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:columnCount="1"
    >
        <TextView
            android:text="2x2 button grid"
            android:textSize="32dip"
            android:layout_gravity="center_horizontal" />
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content" android:orientation="horizontal">
            <Space
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1" />
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Button 1" />
            <Space
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1" />
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="start"
                android:text="Button 2" />
            <Space
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1" />
        </LinearLayout>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
        >
            <Space
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1" />
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Button 3" />
            <Space
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1" />
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="start"
                android:text="Button 4" />
            <Space
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1" />
        </LinearLayout>
    </GridLayout>