Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GridLayout align children within column

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. enter image description here

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 LinearLayouts. Below is my desired result.

enter image description here

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>
like image 681
Chris Horner Avatar asked Aug 20 '14 02:08

Chris Horner


People also ask

How do you center items in GridLayout?

You need to set layout_gravity instead of gravity of textView to make it appear in the centre. You are setting layout_gravity in the xml that is why it works, but dynamically you are only setting gravity .

How do I align a column in CSS?

For aligning columns to the left, the align-content property will set to 'flex-start'. For aligning columns to the right, the align-content property will set to 'flex-end'. For aligning columns to the extreme ends, the align-content property will set to 'space-between'.

How do you align items in CSS grid?

To align the item horizontally within the grid, we use the justify-content property and set it to center . With justify-content we can align the columns start , end , stretch or center .


1 Answers

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: enter image description here

Explanation:

enter image description here

Note:

  • 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:

enter image description here

XML for the grid layout:

<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>
like image 55
Infinite Recursion Avatar answered Sep 18 '22 08:09

Infinite Recursion