GridLayout и проблемы с диапазоном строк / столбцов

121

В представлении блога разработчиков AndroidGridLayout показана эта диаграмма того, как промежутки влияют на автоматическое распределение индекса:

автоматическое размещение индекса

Я пытаюсь реализовать это с помощью файла GridLayout. Вот что у меня есть на данный момент:

<android.support.v7.widget.GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/com.commonsware.android.gridlayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    app:orientation="horizontal"
    app:columnCount="8">

    <Button
        app:layout_columnSpan="2"
        app:layout_rowSpan="2"
        android:layout_gravity="fill_horizontal"
        android:text="@string/string_1"/>

  <Button
    app:layout_columnSpan="2"
    android:layout_gravity="fill_horizontal"
    android:text="@string/string_2"/>

  <Button
    app:layout_rowSpan="4"
    android:text="@string/string_3"/>

  <Button
    app:layout_columnSpan="3"
    app:layout_rowSpan="2"
    android:layout_gravity="fill_horizontal"
    android:text="@string/string_4"/>

  <Button
    app:layout_columnSpan="3"
    android:layout_gravity="fill_horizontal"
    android:text="@string/string_5"/>

  <Button
    app:layout_columnSpan="2"
    android:layout_gravity="fill_horizontal"
    android:text="@string/string_6"/>

  <android.support.v7.widget.Space
    app:layout_column="0"
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

</android.support.v7.widget.GridLayout>

Мне пришлось ввести <Space>элементы, чтобы гарантировать, что каждый столбец имеет минимальную ширину, в противном случае у меня была бы куча столбцов нулевой ширины.

Однако даже с ними я получаю следующее:

образец GridLayout

В частности:

  • Несмотря на это android:layout_gravity="fill_horizontal", мои виджеты с промежутками между столбцами не заполняют составные столбцы

  • Несмотря на android:layout_rowSpanзначения, ничто не охватывает строки

Может ли кто-нибудь воспроизвести диаграмму из сообщения в блоге, используя GridLayout?

Спасибо!

CommonsWare
источник
178
Думаю, даже вы задаете вопросы :)
StackOverflowed

Ответы:

76

Это выглядит довольно хакерским, но мне удалось получить правильный вид, добавив дополнительный столбец и строку сверх того, что необходимо. Затем я заполнил дополнительный столбец пробелом в каждой строке, определяя высоту, и заполнил дополнительную строку пробелом в каждом столбце, определяющем ширину. Для дополнительной гибкости я предполагаю, что эти размеры пространства могут быть установлены в коде, чтобы обеспечить что-то похожее на веса. Пытался добавить скриншот, но у меня нет нужной репутации.

<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnCount="9"
android:orientation="horizontal"
android:rowCount="8" >

<Button
    android:layout_columnSpan="2"
    android:layout_gravity="fill"
    android:layout_rowSpan="2"
    android:text="1" />

<Button
    android:layout_columnSpan="2"
    android:layout_gravity="fill_horizontal"
    android:text="2" />

<Button
    android:layout_gravity="fill_vertical"
    android:layout_rowSpan="4"
    android:text="3" />

<Button
    android:layout_columnSpan="3"
    android:layout_gravity="fill"
    android:layout_rowSpan="2"
    android:text="4" />

<Button
    android:layout_columnSpan="3"
    android:layout_gravity="fill_horizontal"
    android:text="5" />

<Button
    android:layout_columnSpan="2"
    android:layout_gravity="fill_horizontal"
    android:text="6" />

<Space
    android:layout_width="36dp"
    android:layout_column="0"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="1"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="2"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="3"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="4"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="5"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="6"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="7"
    android:layout_row="7" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="0" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="1" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="2" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="3" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="4" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="5" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="6" />

</GridLayout>

Скриншот

kturney
источник
7
Что ж, ИМХО, это постепенно становится менее хакерским, чем другое решение, представленное на сегодняшний день - по крайней мере, здесь жестко запрограммированные размеры находятся в Spaceэлементах. Я добавил скриншот для будущих читателей. Спасибо!
CommonsWare
Почему стоит rowCount8? Нам нужно 4 строки (размер самой большой rowSpan) плюс дополнительная, Spaceтак что должно быть 5. Что мне не хватает?
curioustechizen
Я просто использовал количество строк и столбцов из изображения в исходном вопросе (который сам взят из сообщения в блоге разработчиков Android). Затем я добавил 1 к счетчикам строк и столбцов, чтобы освободить место для внешних граничных пространств. Он должен работать и с 5 рядами.
kturney
5
Я считаю , что это решение работает только с <Gridlayout>в отличие от<android.support.v7.widget.GridLayout>
Didia
Как я могу установить динамически row_span и column span ... это будет работать?
17
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <GridLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:columnCount="8"
        android:rowCount="7" >

        <TextView
            android:layout_width="50dip"
            android:layout_height="50dip"
            android:layout_columnSpan="2"
            android:layout_rowSpan="2"
            android:background="#a30000"
            android:gravity="center"
            android:text="1"
            android:textColor="@android:color/white"
            android:textSize="20dip" />

        <TextView
            android:layout_width="50dip"
            android:layout_height="25dip"
            android:layout_columnSpan="2"
            android:layout_rowSpan="1"
            android:background="#0c00a3"
            android:gravity="center"
            android:text="2"
            android:textColor="@android:color/white"
            android:textSize="20dip" />

        <TextView
            android:layout_width="25dip"
            android:layout_height="100dip"
            android:layout_columnSpan="1"
            android:layout_rowSpan="4"
            android:background="#00a313"
            android:gravity="center"
            android:text="3"
            android:textColor="@android:color/white"
            android:textSize="20dip" />

        <TextView
            android:layout_width="75dip"
            android:layout_height="50dip"
            android:layout_columnSpan="3"
            android:layout_rowSpan="2"
            android:background="#a29100"
            android:gravity="center"
            android:text="4"
            android:textColor="@android:color/white"
            android:textSize="20dip" />

        <TextView
            android:layout_width="75dip"
            android:layout_height="25dip"
            android:layout_columnSpan="3"
            android:layout_rowSpan="1"
            android:background="#a500ab"
            android:gravity="center"
            android:text="5"
            android:textColor="@android:color/white"
            android:textSize="20dip" />

        <TextView
            android:layout_width="50dip"
            android:layout_height="25dip"
            android:layout_columnSpan="2"
            android:layout_rowSpan="1"
            android:background="#00a9ab"
            android:gravity="center"
            android:text="6"
            android:textColor="@android:color/white"
            android:textSize="20dip" />
    </GridLayout>

</RelativeLayout>

Скриншот

HandlerExploit
источник
2
Спасибо! Что интересно, если я переключусь на GridLayoutиз пакета поддержки Android, макет сломается, что говорит о том, что они не полностью совместимы. Кроме того, я очень надеюсь, что есть способ сделать это, не требующий жесткой привязки размеров виджетов. Я ненадолго позволю этому ролику, чтобы посмотреть, какие еще ответы появятся (если они есть), но я приму ваш, если ничего лучше не появится. Еще раз спасибо!
CommonsWare
4
«если я переключусь на GridLayout из пакета поддержки Android, макет сломается» - собственно, это была моя ошибка, я не преобразовал требуемые android:атрибуты в атрибуты app:, используя пространство имен XML backport. Он действительно работает с задним портом.
CommonsWare
Я нашел способ иметь некоторые из них динамического размера, но только в том случае, если полная ширина столбцов или строк уже определена смежными представлениями. Я не думаю, что они работают как гири и равномерно распределяют пространство в зависимости от заданных пролетов. Это не идеально, но отлично работает для того, что мне нужно в моем текущем проекте.
HandlerExploit 09
Что ж, ваш пример больше похож на подход AbsoluteLayout, смешанный с подходом для RelativeLayout, не так ли? Это не динамично и не переносимо. Зачем именно для этого нужен GridLayout? В любом случае, GridLayout, имхо, либо сломанный, либо незаконченный ...
Bondax
@Bondax Эта реализация четко определяет элемент сетки как по высоте, так и по ширине, ширине столбца и ширине столбца. Макет сетки будет перемещать элементы сетки в ограниченном пространстве, если для сетки задана разная ширина (ширина экрана). Это было требованием для проекта, и это отлично решило проблему.
HandlerExploit
6

Вы должны установить как layout_gravity, так и layout_columntWeight для своих столбцов

<android.support.v7.widget.GridLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView android:text="سوم شخص"
        app:layout_gravity="fill_horizontal"
        app:layout_columnWeight="1"
        />

    <TextView android:text="دوم شخص"
        app:layout_gravity="fill_horizontal"
        app:layout_columnWeight="1"
        />

    <TextView android:text="اول شخص"
        app:layout_gravity="fill_horizontal"
        app:layout_columnWeight="1"
        />
 </android.support.v7.widget.GridLayout>
Хоссейн Шахдуст
источник
2

Библиотека GridLayout для поддержки Android V7 упрощает распределение избыточного пространства, учитывая принцип веса. Чтобы растянуть колонну, убедитесь, что компоненты внутри нее определяют вес или силу тяжести. Чтобы столбец не растягивался, убедитесь, что один из компонентов в столбце не определяет вес или силу тяжести. Не забудьте добавить зависимость для этой библиотеки. Добавьте com.android.support:gridlayout-v7:25.0.1 в build.gradle.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:columnCount="2"
app:rowCount="2">

<TextView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:gravity="center"
    android:text="First"
    app:layout_columnWeight="1"
    app:layout_rowWeight="1" />

<TextView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:gravity="center"
    android:text="Second"
    app:layout_columnWeight="1"
    app:layout_rowWeight="1" />

<TextView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:gravity="center"
    android:text="Third"
    app:layout_columnWeight="1"
    app:layout_rowWeight="1" />

<TextView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:gravity="center"        
    app:layout_columnWeight="1"
    app:layout_rowWeight="1"
    android:text="fourth"/>

</android.support.v7.widget.GridLayout>
Permita
источник