I have a GridLayout
that consists of 6 children. It has a column count of 2. The left column's children have a layout_gravity
of start|end|fill_horizontal
and layout_width
of 0dp, which causes them to fill all available space.
This is great, and gives me the output shown below.
Views 4, 5, and 6 are only as big as they need to be. Very cool. I would now like to align views 4, 5, and 6 to the right hand side of the container, but this has proved challenging. Because of the way GridLayout
determines column flexibility, giving the right column's views a layout_gravity
of right
ruins the layout. Views in the first column no longer fill the remaining width in the layout. (From my understanding, this is because now both columns have children defining a horizontal gravity, so GridLayout
can no longer mark one column as flexible).
Is there a way to achieve this? I'm really not keen on nesting LinearLayout
s. Below is my desired result.
For reference, the current view hierarchy XML looks something like...
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnCount="2">
<View
android:id="@+id/view1"
android:layout_gravity="start|end|fill_horizontal" />
<View
android:id="@+id/view4" />
<View
android:id="@+id/view2"
android:layout_gravity="start|end|fill_horizontal" />
<View
android:id="@+id/view5" />
<View
android:id="@+id/view3"
android:layout_gravity="start|end|fill_horizontal" />
<View
android:id="@+id/view6" />
</GridLayout>
From the Documentation of GridLayout:
Excess Space Distribution
Multiple components in the same row or column group are considered to act in parallel. Such a group is flexible only if all of the components within it are flexible. Row and column groups that sit either side of a common boundary are instead considered to act in series. The composite group made of these two elements is flexible if one of its elements is flexible.
To make a column stretch, make sure all of the components inside it define a gravity. To prevent a column from stretching, ensure that one of the components in the column does not define a gravity.
When the principle of flexibility does not provide complete disambiguation, GridLayout's algorithms favour rows and columns that are closer to its right and bottom edges.
(emphasis mine)
So, to design the following output:
Don't align the gravity of the largest width component of the right column with any axis (such as top, bottom, left, right). When a view is aligned w.r.t to axis, it will not stretch because the composite group will become non-flexible. This will make the other elements in the composite group shrink (even if fill_horizontal is specified, it will be ineffective in a non-flexible composite group). The width of the widest component will be the width of the right side column in the grid.
If you want the text to wrap when the length of the content increases, specify width of the view as 0dp (android:layout_width="0dp"
), so that the grid layout will dynamically calculate the width:
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:alignmentMode="alignBounds"
android:background="#ffffffff"
android:columnCount="6"
android:columnOrderPreserved="false"
android:orientation="horizontal"
android:padding="5dp"
android:useDefaultMargins="true" >
<Button
android:id="@+id/view1"
android:layout_width="0dp"
android:layout_columnSpan="4"
android:layout_gravity="left|fill"
android:background="#ff00BFFF"
android:text="View 1" />
<Button
android:id="@+id/view4"
android:layout_columnSpan="2"
android:layout_gravity="right|clip_horizontal"
android:background="#ffff0000"
android:padding="5dp"
android:text="hi"
android:textColor="#ffffffff" />
<Button
android:id="@+id/view2"
android:layout_width="0dp"
android:layout_columnSpan="4"
android:layout_gravity="left|fill"
android:background="#ff00ff00"
android:text="View 2 has a very very very long text" />
<Button
android:id="@+id/view5"
android:layout_columnSpan="2"
android:layout_gravity="clip_horizontal"
android:background="#ffDDA0DD"
android:padding="5dp"
android:text="hello something"
android:textColor="#ffffffff" />
<Button
android:id="@+id/view3"
android:layout_width="0dp"
android:layout_columnSpan="4"
android:layout_gravity="left|fill"
android:background="#ffffD700"
android:text="View 3 has a very very very long text" />
<Button
android:id="@+id/view6"
android:layout_columnSpan="2"
android:layout_gravity="clip_horizontal|right"
android:background="#ff4169E1"
android:padding="5dp"
android:text="hello world"
android:textColor="#ffffffff" />
</GridLayout>