Как указать ширину и высоту ячеек Android GridLayout в относительных показателях?

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

Скажем, я хочу две-две сетки, где каждая ячейка занимает ровно 25% экранной недвижимости (половина высоты, половина ширины). Могу ли я это сделать?

С LinearLayout я выполнил бы это, вставив два горизонтальных LinearLayout в одну вертикаль, а затем присвойв весу 1 для всех элементов. GridLayout не поддерживает весовое свойство.

Ответ 1

Есть два свойства android: layout_columnWeight и layout_rowWeight, которые работают как layout_weight в LinearLayout. Это поддерживается в API 21. Для более старых устройств Android используйте GridLayout из библиотеки поддержки v7.

Эти свойства позволят вам настроить ширину/высоту базы столбцов на значение, присвоенное каждому столбцу. Формула выглядит следующим образом (column_weight/sum_of_column_weight) * gridLayout_width = column_width.

Здесь пример, который представляет собой сетку с двумя строками и двумя столбцами, равномерно распределенными, каждый занимает 50% от веса и высоты сетки.

<GridLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:columnCount="2"
>

    <TextView
        android:text="SEARCH FEE"
        android:layout_columnWeight="1"
        android:layout_rowWeight="1"
     />

    <TextView
        android:layout_columnWeight="1"
        android:text="SEARCH FEE"
        android:layout_rowWeight="1"
     />

    <TextView
        android:text="SEARCH FEE"
        android:layout_columnWeight="1"
        android:layout_rowWeight="1"
        />

    <TextView
        android:layout_columnWeight="1"
        android:text="SEARCH FEE"
        android:layout_rowWeight="1"
        />
</GridLayout>

Ответ 2

похоже, что установка его по своему усмотрению должна быть достаточно простой в соответствии с документацией:

android:rowCount='2'
android:columnCount='2'

и в дочерних наборах

android:layout_columnSpan="1"
android:layout_rowSpan="1"

В этой ссылке также упоминается растяжка:

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

Который бы выглядел как решение сохранить строки и столбцы в соотношении 50:50 без изменения размера в соответствии с содержанием

Ответ 3

Это будет примерно так:

<?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="1"
        app:layout_columnWeight="1"
        app:layout_rowWeight="1" />

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

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

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

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

Ответ 4

В GridLayout есть вспомогательный метод:

GridLayout.LayoutParams params = new GridLayout.LayoutParams();
            params.columnSpec = GridLayout.spec(GridLayout.UNDEFINED, 1, getAlignment(Gravity.NO_GRAVITY, true), 1);
item.setLayoutParams(params);

private GridLayout.Alignment getAlignment(int gravity, boolean horizontal) {
        int mask = horizontal ? HORIZONTAL_GRAVITY_MASK : VERTICAL_GRAVITY_MASK;
        int shift = horizontal ? AXIS_X_SHIFT : AXIS_Y_SHIFT;
        int flags = (gravity & mask) >> shift;
        switch (flags) {
            case (AXIS_SPECIFIED | AXIS_PULL_BEFORE):
                return horizontal ? LEFT : TOP;
            case (AXIS_SPECIFIED | AXIS_PULL_AFTER):
                return horizontal ? RIGHT : BOTTOM;
            case (AXIS_SPECIFIED | AXIS_PULL_BEFORE | AXIS_PULL_AFTER):
                return FILL;
            case AXIS_SPECIFIED:
                return CENTER;
            case (AXIS_SPECIFIED | AXIS_PULL_BEFORE | GravityCompat.RELATIVE_LAYOUT_DIRECTION):
                return START;
            case (AXIS_SPECIFIED | AXIS_PULL_AFTER | GravityCompat.RELATIVE_LAYOUT_DIRECTION):
                return END;
            default:
                return GridLayout.FILL;
        }
    }

Обычно это только доступное отражение мысли.

И меньшая версия:

params.columnSpec = GridLayout.spec(GridLayout.UNDEFINED, 1, GridLayout.FILL, 1);