GridLayout выровняет дочерние элементы в столбце

У меня есть GridLayout, состоящий из 6 детей. Он имеет число столбцов 2. У детей с левым столбцом есть layout_gravity of start|end|fill_horizontal и layout_width 0dp, что заставляет их заполнять все свободное пространство.

Это здорово и дает мне результат, показанный ниже. enter image description here

Представления 4, 5 и 6 являются настолько большими, насколько они должны быть. Очень круто. Теперь я хотел бы выровнять точки 4, 5 и 6 с правой стороны контейнера, но это оказалось сложным. Из-за способа GridLayout определяется гибкость столбцов, давая правильные представления столбцов layout_gravity of right разрушает макет. Представления в первом столбце больше не заполняют оставшуюся ширину в макете. (По моему мнению, это потому, что теперь в обоих столбцах есть дети, определяющие горизонтальную гравитацию, поэтому GridLayout не может больше отмечать один столбец как гибкий).

Есть ли способ достичь этого? Я действительно не заинтересован в вложенности LinearLayout s. Ниже мой желаемый результат.

enter image description here

Для справки, текущая иерархия представлений XML выглядит примерно так...

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

Ответ 1

Из документа GridLayout:

Распределение избыточного пространства

Несколько компонентов в той же группе строк или столбцов считаются параллельными. Такая группа гибкая, только если все компоненты внутри нее гибкие. Вместо этого считается, что группы строк и столбцов, которые расположены по обе стороны от общей границы, действуют последовательно. Составная группа, состоящая из этих двух элементов, является гибкой, если один из ее элементов является гибким.

Чтобы сделать растяжку столбца, убедитесь, что все компоненты внутри него определяют гравитацию. Чтобы предотвратить растяжение столбца, убедитесь, что один из компонентов в столбце не определяет гравитацию.

Когда принцип гибкости не дает полного устранения, алгоритмы GridLayout предпочитают строки и столбцы, которые ближе к его правому и нижнему краям.

(акцент мой)

Итак, чтобы создать следующий вывод: enter image description here

Объяснение:

enter image description here

Примечание:

  • Не выравнивайте гравитацию самого большого компонента ширины правого столбца с любой осью (например, сверху, снизу, слева, справа). Когда представление выровнено по оси w.r.t, оно не будет растягиваться, потому что составная группа станет негибкой. Это приведет к сокращению других элементов в составной группе (даже если задано значение fill_horizontal, оно будет неэффективным в негибкой составной группе). Ширина самого широкого компонента будет равна ширине столбца правой стороны в сетке.

  • Если вы хотите, чтобы текст обертывался при увеличении длины содержимого, укажите ширину представления как 0dp (android:layout_width="0dp"), так что макет сетки будет динамически вычислять ширину:

enter image description here

XML для макета сетки:

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

Ответ 2

Позвольте мне изменить свой ответ и использовать другой подход. Это файл макета:

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnCount="2" >


<TextView
    android:id="@+id/TextView1"
    android:layout_column="0"
    android:layout_columnSpan="1"
    android:layout_row="0"
    android:background="#87CEFA"
    android:text="@string/view1" />

<TextView
    android:id="@+id/TextView4"
    android:gravity="right"
    android:layout_column="1"
    android:layout_columnSpan="1"
    android:layout_row="0"
    android:layout_gravity="right"
    android:background="#FF3030"
    android:text="@string/view4" />

<TextView
    android:id="@+id/TextView2"
    android:layout_column="0"
    android:layout_columnSpan="1"
    android:layout_row="1"
    android:width="0dp"
    android:layout_gravity="fill_horizontal"
    android:background="#90EE90"
    android:text="@string/view2" />

<TextView
    android:id="@+id/TextView5"
    android:gravity="right"
    android:layout_column="1"
    android:layout_columnSpan="1"
    android:layout_row="1"
    android:background="#EE82EE"
    android:paddingLeft="36dp"
    android:layout_gravity="right"
    android:text="@string/view5" />

<TextView
    android:id="@+id/TextView3"
    android:layout_column="0"
    android:layout_columnSpan="1"
    android:layout_row="2"
    android:width="0dp"
    android:layout_gravity="fill_horizontal"
    android:background="#EEEE00"
    android:text="@string/view3" />

<TextView
    android:id="@+id/TextView6"
    android:gravity="right"
    android:layout_column="1"
    android:layout_columnSpan="1"
    android:layout_row="2"
    android:background="#EE7621"
    android:layout_gravity="right"
    android:text="@string/view6" />

</GridLayout>

И вот результат:

enter image description here

Ширина обоих столбцов определяется содержимым. Для View 5 я добавил дополнение с левой стороны, то есть прокладка может использоваться для расширения ширины (и высоты) ячеек. Будет ли это работать?