Грид

Последнее обновление: 03.04.2024

Компоненты LazyVerticalGrid и LazyHorizontalGrid обеспечивают отображение элементов в виде сетки. Эти компоненты похожи на списки LazyColumn/LazyRow, только для описания содержимого применяют интерфейс LazyGridScope

LazyHorizontalGrid

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

@Composable
fun LazyHorizontalGrid(
    rows: GridCells,
    modifier: Modifier = Modifier,
    state: LazyGridState = rememberLazyGridState(),
    contentPadding: PaddingValues = PaddingValues(0.dp),
    reverseLayout: Boolean = false,
    horizontalArrangement: Arrangement.Horizontal = if (!reverseLayout) Arrangement.Start else Arrangement.End,
    verticalArrangement: Arrangement.Vertical = Arrangement.Top,
    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
    userScrollEnabled: Boolean = true,
    content: LazyGridScope.() -> Unit
): Unit
  • rows: представляет тип GridCells, который описывает количество и размер строк

  • modifier: применяемые к контейнеру модификаторы

  • state: объект состояния LazyGridState, применяемый для управления состоянием контейнера

  • contentPadding: отступы вокруг содержимого

  • reverseLayout: при значении true располагает элементы в обратном порядке

  • verticalArrangement: настройки расположения элементов по горизонтали

  • horizontalArrangement: выравнивание элементов по вертикали

  • flingBehavior: описывает поведение при таком типе прокрутки, когда пользователь быстро перетаскивает что-то и поднимает палец. Представляет объект FlingBehavior

  • userScrollEnabled: указывает, доступна ли прокрутка жестами либо через специальные инструменты управления доступом

  • content: устанавливает содержимое контейнера с помощью функции типа LazyGridScope.() -> Unit.

Для установки содержимого интерфейс LazyGridScope предоставляет несколько функций:

  • LazyListScope.item(): для добавления одного элемента

  • LazyListScope.items(): для добавления нескольких элементов

  • LazyListScope.itemsIndexed(): для добавления нескольких элементов с использованием индексов

Для определения количества и размера ячеек применяется интерфейс GridCells. В частности, он предоставляет следующие методы:

  • GridCells.Adaptive: определяет сетку с максимально возможным количеством строк или столбцов при условии, что каждая ячейка имеет как минимум пространство minSize и все дополнительное пространство распределено равномерно.

  • GridCells.Исправлено: определяет сетку с фиксированным количеством строк или столбцов.

  • GridCells.FixedSize: определяет сетку с максимально возможным количеством строк или столбцов при условии, что каждая ячейка занимает ровное пространство.

Например, определим простейший грид из текстовых элементов:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val itemsList = (0..12).toList()
            LazyHorizontalGrid(
                rows = GridCells.Fixed(3),
                modifier = Modifier.fillMaxSize()
            ){
                items(itemsList) {item ->
                    Text("Item $item", fontSize = 28.sp,modifier= Modifier.padding(8.dp))
                }
            }
        }
    }
}

В данном случае для создания грида применяется список itemsList из 13 элементов. С помощью параметра

rows = GridCells.Fixed(3)

определяем три строки. Для заполнения этих строк вызывается функция items()

items(itemsList) {item ->
    Text("Item $item", fontSize = 28.sp,modifier= Modifier.padding(8.dp))
}

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

LazyHorizontalGrid в Jetpack Compose и Kotlin на Android

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

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.background
import androidx.compose.ui.graphics.Color
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.ui.Alignment
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val langs = listOf(Language("Kotlin", 0xff16a085),
                Language("Java", 0xff2980b9),
                Language("JavaScript", 0xff8e44ad),
                Language("Python", 0xff2c3e50),
                Language("Rust",0xffd35400),
                Language("C#",0xff27ae60),
                Language("C++",0xfff39c12),
                Language("Go",0xff1abc9c))
            LazyHorizontalGrid(
                rows = GridCells.Fixed(2),
                modifier = Modifier.fillMaxSize(),
                horizontalArrangement = Arrangement.Center
            ){
                items(langs) {lang ->
                    Column(Modifier.padding(8.dp).size(125.dp), horizontalAlignment = Alignment.CenterHorizontally){
                        Box(Modifier.size(100.dp).background(Color(lang.hexColor)))
                        Text(lang.name, fontSize = 24.sp,modifier= Modifier.padding(5.dp))
                    }
                }
            }
        }
    }
}

data class Language(val name:String, val hexColor: Long)

Здесь для представления данных применяется класс Language, который хранит название языка программирования и связанный с ним цвет. А список langs хранит набор объектов Language. Для вывода этого списка в грид создается компонент LazyHorizontalGrid с 2-мя столбцами. Внутри каждой ячейки отображаем Box, закрашенный в определенный цвет, и текст с названием языка.

Строки LazyHorizontalGrid в Jetpack Compose и Kotlin на Android

Обратите внимание, что два элемента не поместились на экране смартфона, и для их просмотра надо использовать горизонтальную прокрутку.

LazyVerticalGrid

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

@Composable
fun LazyVerticalGrid(
    columns: GridCells,
    modifier: Modifier = Modifier,
    state: LazyGridState = rememberLazyGridState(),
    contentPadding: PaddingValues = PaddingValues(0.dp),
    reverseLayout: Boolean = false,
    verticalArrangement: Arrangement.Vertical = if (!reverseLayout) Arrangement.Top else Arrangement.Bottom,
    horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
    userScrollEnabled: Boolean = true,
    content: LazyGridScope.() -> Unit
): Unit
  • columns: представляет объект GridCells, который описывает количество и размер столбцов

  • modifier: применяемые к контейнеру модификаторы

  • state: объект состояния LazyGridState, применяемый для управления состоянием контейнера

  • contentPadding: отступы вокруг содержимого

  • reverseLayout: при значении true располагает элементы в обратном порядке

  • verticalArrangement: настройки расположения элементов по вертикали

  • horizontalArrangement: выравнивание элементов по горизонтали

  • flingBehavior: описывает поведение при таком типе прокрутки, когда пользователь быстро перетаскивает что-то и поднимает палец. Представляет объект FlingBehavior

  • userScrollEnabled: указывает, доступна ли прокрутка жестами либо через специальные инструменты управления доступом

  • content: устанавливает содержимое контейнера с помощью функции типа LazyGridScope.() -> Unit.

LazyVerticalGrid во многом аналогичен LazyHorizontalGrid. Так, перепишем предыдущий пример с использованием LazyVerticalGrid:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.background
import androidx.compose.ui.graphics.Color
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.ui.Alignment
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val langs = listOf(Language("Kotlin", 0xff16a085),
                Language("Java", 0xff2980b9),
                Language("JavaScript", 0xff8e44ad),
                Language("Python", 0xff2c3e50),
                Language("Rust",0xffd35400),
                Language("C#",0xff27ae60),
                Language("C++",0xfff39c12),
                Language("Go",0xff1abc9c))
            LazyVerticalGrid(
                columns = GridCells.Fixed(2),
                modifier = Modifier.fillMaxSize(),
                horizontalArrangement = Arrangement.Center
            ){
                items(langs) {lang ->
                    Column(Modifier.padding(8.dp), horizontalAlignment = Alignment.CenterHorizontally){
                        Box(Modifier.size(100.dp).background(Color(lang.hexColor)))
                        Text(lang.name, fontSize = 24.sp,modifier= Modifier.padding(5.dp))
                    }
                }
            }
        }
    }
}


data class Language(val name:String, val hexColor: Long)
LazyVerticalGrid в Jetpack Compose и Kotlin на Android

Здесь практически то же самое, только в LazyVerticalGrid вместо строк здесь задаем 2 столбца. Соответственно сначала элементы заполняются 2 стобца первой строки. Если после этого еще есть элементы, то создается вторая строка и так далее. А чтобы просмотреть те элементы, которые не поместились на экране, надо использовать вертикальную прокрутку.

Адаптивные размеры

В примерах выше применялось точное количество строк/столбцов. Для этого использовался метод GridCells.Fixed(), в который передавалось количество строк/столбцов. Теперь рассмотрим другие возможности установки размеров. Так, метод GridCells.Adaptive(). Он определяет сетку с максимально возможным количеством строк или столбцов при условии, что каждая ячейка имеет как минимум размер minSize и все дополнительное пространство распределено равномерно. Значение minSize, которе указывает на минимаьную высоту строки или минимальную ширину столбца, передается в метод GridCells.Adaptive() в качестве единственного параметра. Например:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.background
import androidx.compose.ui.graphics.Color
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.ui.Alignment
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.material3.Text

import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val langs = listOf(Language("Kotlin", 0xff16a085),
                Language("Java", 0xff2980b9),
                Language("JavaScript", 0xff8e44ad),
                Language("Python", 0xff2c3e50),
                Language("Rust",0xffd35400),
                Language("C#",0xff27ae60),
                Language("C++",0xfff39c12),
                Language("Go",0xff1abc9c))
            LazyVerticalGrid(
                columns = GridCells.Adaptive(minSize=120.dp),
                modifier = Modifier.fillMaxSize(),
                horizontalArrangement = Arrangement.Center
            ){
                items(langs) {lang ->
                    Column(Modifier.padding(7.dp), horizontalAlignment = Alignment.CenterHorizontally){
                        Box(Modifier.size(100.dp).background(Color(lang.hexColor)))
                        Text(lang.name, fontSize = 24.sp)
                    }
                }
            }
        }
    }
}

data class Language(val name:String, val hexColor: Long)

В данном случае создается вертикальный грид, в котором минимальная ширина каждой ячейки равна 120 пикселей:

columns = GridCells.Adaptive(minSize=120.dp)

Минимальную ширину в данном случае я определил на основе содержимого ячейки. В итоге при вертикальной ориентации на моем устройстве будет создано 3 столбца

Настройка столбцов в LazyVerticalGrid в Jetpack Compose и Kotlin на Android

Тогда как при горизонтальной ориентации будет создаваться аж 5 столбцов

Адаптивные размеры в LazyVerticalGrid в Jetpack Compose и Kotlin на Android

Данный подход может показать лучше, чем установка фиксированного количества строк/столбцов, поскольку экранное пространство устройства расходуется более экономично.

Установка точных размеров

Еще один метод GridCells.FixedSize() позволяет задать точный размер ячейки (ширину столбцов или высоту строк). В этом случае создается максимально возможное количество строк или столбцов при условии, что каждая ячейка имеет указанный размер. Значение размера передается в метод GridCells.FixedSize() в качестве единственного параметра. Например:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.background
import androidx.compose.ui.graphics.Color
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.ui.Alignment
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.material3.Text

import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val langs = listOf(Language("Kotlin", 0xff16a085),
                Language("Java", 0xff2980b9),
                Language("JavaScript", 0xff8e44ad),
                Language("Python", 0xff2c3e50),
                Language("Rust",0xffd35400),
                Language("C#",0xff27ae60),
                Language("C++",0xfff39c12),
                Language("Go",0xff1abc9c))
            LazyVerticalGrid(
                columns = GridCells.FixedSize(size=140.dp),
                modifier = Modifier.fillMaxSize(),
                horizontalArrangement = Arrangement.Center
            ){
                items(langs) {lang ->
                    Column(Modifier.padding(7.dp), horizontalAlignment = Alignment.CenterHorizontally){
                        Box(Modifier.size(100.dp).background(Color(lang.hexColor)))
                        Text(lang.name, fontSize = 24.sp)
                    }
                }
            }
        }
    }
}

data class Language(val name:String, val hexColor: Long)

В данном случае создается вертикальный грид, в котором ширина каждой ячейки должна быть равна 140 пикселей:

columns = GridCells.FixedSize(size=140.dp)

В итоге при вертикальной ориентации на моем устройстве будет создано 2 столбца

Точные размеры столбцов в LazyVerticalGrid в Jetpack Compose и Kotlin на Android

Тогда как при горизонтальной ориентации будет создаваться 4 столбца

GridCells в LazyVerticalGrid в Jetpack Compose и Kotlin на Android
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850