В прошлой статье были рассмотрены гриды - компоненты LazyVerticaldGrid
и LazyHorizontalGrid
, которые позволяют табличные представления со строками и столбцами.
Но эти компоненты имеют недостаток - все ячейки этих гридов имеют одинаковый размер (в рамках одной строки или столбца). И для решения этой проблемы были предложены новые типы компонентов -
LazyVerticalStaggeredGrid и LazyHorizontalStaggeredGrid
Компонент LazyVerticalStaggeredGrid представляет вертикальную сетку. Как и другие lazy-контейнеры, этот компонент компонует и размещает только элементы, которые видимые в данный момент на экране. Он имеет следующие параметры:
@Composable fun LazyVerticalStaggeredGrid( columns: StaggeredGridCells, modifier: Modifier = Modifier, state: LazyStaggeredGridState = rememberLazyStaggeredGridState(), contentPadding: PaddingValues = PaddingValues(0.dp), reverseLayout: Boolean = false, verticalItemSpacing: Dp = 0.dp, horizontalArrangement: Arrangement.Horizontal = Arrangement.spacedBy(0.dp), flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(), userScrollEnabled: Boolean = true, content: LazyStaggeredGridScope.() -> Unit ): Unit
columns
: представляет размер и количество столбцов в виде объекта StaggeredGridCells
modifier
: применяемые к компоненту модификаторы
state
: состояние в виде объекта LazyStaggeredGridState
. Для его создания применяется функция rememberLazyStaggeredGridState()
contentPadding
: отступы вокруг контента
reverseLayout
: указывает, будут ли элементы грида располагаться в обратном порядке
horizontalArrangement
: определяет расположение элементов по горизонтали
verticalItemSpacing
: вертикальные отступы между элементами
flingBehavior
: описывает поведение при таком типе прокрутки, когда пользователь быстро перетаскивает что-то и поднимает палец.
userScrollEnabled
: указывает, будет ли доступна прокрутка
content
: представляет функцию типа LazyStaggeredGridScope.() -> Unit
, которая задает вложенные компоненты.
Для добавления элементов в грид можно использовать функции LazyStaggeredGridScope.items()
(для списка объектов) или LazyStaggeredGridScope.item()
(для одного элемента)
Рассмотрим на примере. Возьмем следующее приложение:
package com.example.helloapp import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import kotlin.random.Random class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { LazyVerticalStaggeredGrid( columns = StaggeredGridCells.Fixed(3), // 3 столбца modifier = Modifier.fillMaxSize(), contentPadding = PaddingValues(8.dp), horizontalArrangement = Arrangement.spacedBy(8.dp), verticalItemSpacing = 8.dp ){ items(50) {_ -> Box(Modifier .fillMaxWidth() .height(Random.nextInt(50, 200).dp) .background(Color( Random.nextInt(255), Random.nextInt(255), Random.nextInt(255), 255 )) ) } } } } }
Для LazyVerticalStaggeredGrid устанавливаем три столбца:
columns = StaggeredGridCells.Fixed(3)
Расстояние от границ контейнера до содержимого будет составлять 8 пикселей:
contentPadding = PaddingValues(8.dp)
Расстояние между столбцами по горизонтали будет также составлять 8 пикселей:
horizontalArrangement = Arrangement.spacedBy(8.dp)
И также 8 пикселей будет составлять вертикальные расстояния между элементами в столбце:
verticalItemSpacing = 8.dp
Для создания вложенных элементов здесь применяется функция LazyStaggeredGridScope.items()
. Ей передается количество создаваемых элементов - в данном случае 50. Причем каждый элемент представляет компонент Box:
items(50) {_ -> Box(Modifier .fillMaxWidth() .height(Random.nextInt(50, 200).dp) .background(Color( Random.nextInt(255), Random.nextInt(255), Random.nextInt(255), 255 )) ) }
Для показательности высота и цвет компонентов Box устанавливается на основе случайных чисел. В итоге мы получим зубчатое расположение элементов наподобие следующего:
Компонент LazyHorizontalStaggeredGrid представляет горизонтальную сетку. Как и другие lazy-контейнеры, этот компонент компонует и размещает только элементы, которые видимые в данный момент на экране. Он имеет следующие параметры:
@Composable fun LazyHorizontalStaggeredGrid( rows: StaggeredGridCells, modifier: Modifier = Modifier, state: LazyStaggeredGridState = rememberLazyStaggeredGridState(), contentPadding: PaddingValues = PaddingValues(0.dp), reverseLayout: Boolean = false, verticalArrangement: Arrangement.Vertical = Arrangement.spacedBy(0.dp), horizontalItemSpacing: Dp = 0.dp, flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(), userScrollEnabled: Boolean = true, content: LazyStaggeredGridScope.() -> Unit ): Unit
rows
: представляет размер и количество строк в виде объекта StaggeredGridCells
modifier
: применяемые к компоненту модификаторы
state
: состояние в виде объекта LazyStaggeredGridState
. Для его создания применяется функция rememberLazyStaggeredGridState()
contentPadding
: отступы вокруг контента
reverseLayout
: указывает, будут ли элементы грида располагаться в обратном порядке
verticalArrangement
: определяет расположение элементов по вертикали
horizontalItemSpacing
: горизонтальные отступы между элементами
flingBehavior
: описывает поведение при таком типе прокрутки, когда пользователь быстро перетаскивает что-то и поднимает палец.
userScrollEnabled
: указывает, будет ли доступна прокрутка
content
: представляет функцию типа LazyStaggeredGridScope.() -> Unit
, которая задает вложенные компоненты.
Для добавления элементов в грид можно использовать функции LazyStaggeredGridScope.items()
(для списка объектов) или LazyStaggeredGridScope.item()
(для одного элемента)
Изменим предыдущий пример, использовав LazyHorizontalStaggeredGrid:
package com.example.helloapp import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.staggeredgrid.LazyHorizontalStaggeredGrid import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells import androidx.compose.ui.tooling.preview.Preview import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import kotlin.random.Random class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { LazyHorizontalStaggeredGrid( rows = StaggeredGridCells.Fixed(3), modifier = Modifier.fillMaxSize(), contentPadding = PaddingValues(8.dp), horizontalItemSpacing = 8.dp, verticalArrangement = Arrangement.spacedBy(8.dp) ){ items(50) {_ -> Box(Modifier .fillMaxHeight() .width(Random.nextInt(50, 200).dp) .background(Color( Random.nextInt(255), Random.nextInt(255), Random.nextInt(255), 255 )) ) } } } } }
Здесь все почти аналогично, только теперь создаем три строки.
LazyHorizontalStaggeredGrid( rows = StaggeredGridCells.Fixed(3),
Кроме того, у компонентов Box в качестве ширины устанавливаем случайное значение. В итоге мы получим интерфейс наподобие следующего: