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 определяет гибкость столбца, предоставляя представления правого столбца a layout_gravity of right руины макета. Виды в первом столбце больше не заполняют оставшуюся ширину макета. (Насколько я понимаю, это потому, что теперь у обоих столбцов есть дети, определяющие горизонтальную гравитацию, поэтому GridLayout больше не может отмечать один столбец как гибкий).

есть ли способ достичь этого? Я действительно не люблю гнездиться LinearLayouts. Ниже мое желание результат.

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>

2 ответов


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

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

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

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

когда принцип гибкости не обеспечивает полной омонимии, алгоритмы 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>

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

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

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