Если вы следите за последними обновлениями Jetpack Compose, вы, возможно, слышали о новых композитах FlowRow и FlowColumn, недавно добавленных в Jetpack Compose 1.4.1. Конечно, они уже некоторое время были опубликованы в Accompanist (группа библиотек, призванных дополнить Jetpack Compose функциями, часто необходимыми разработчикам, но пока недоступными в основной версии). Но теперь они доступны в базовом фреймворке, и было бы здорово посмотреть, для чего их можно использовать.
Самая важная идея в этой компоновке заключается в том, что мы можем выкладывать элементы в контейнер, когда размер элементов или контейнера неизвестен или динамичен. Например, здесь у нас есть чипсы (теги), которые мы размещаем в случайном порядке. Фишка «Plant-based food» не помещается и переносится на следующую строку.
FlowRow { chipsInRow.forEach { Chip(text = it.text, pointColor = it.pointColor) } }
FlowColumn может выглядеть следующим образом:
FlowColumn { cardsInColumn.forEach { cardData -> Card(cardData) } }
Давайте посмотрим на API:
- horizontalArrangement помогает расположить элементы по горизонтали в определенном порядке.
- verticalAlignment помогает выровнять элементы, если они имеют разную высоту (хотя это не должно быть распространенным случаем).
- maxItemsInEachRow указывает максимальное количество элементов, которые мы можем разместить в строке.
Это очень удобно использовать в сочетании с модификаторами веса.
fun FlowRow( modifier: Modifier = Modifier, horizontalArrangement: Arrangement.Horizontal = Arrangement.Start, verticalAlignment: Alignment.Vertical = Alignment.Top, maxItemsInEachRow: Int = Int.MAX_VALUE, content: @Composable RowScope.() -> Unit )
Для FlowColumn параметры работают так же, только для вертикали.
VerticalAlignment предлагает 3 различных варианта, которые очевидны:
HorizontalArrangement, с другой стороны, имеет больше возможностей работы с некоторыми неочевидными вариантами:
Различие между SpaceEvenly и SpaceAround может быть неочевидным. Основное различие заключается в том, что SpaceEvenly, как следует из названия, обеспечивает равномерный интервал, включая начальные и конечные поля. SpaceAround работает так же, но поля занимают в два раза меньше места, чем расстояние между внутренними элементами. В качестве альтернативы можно использовать абсолютное значение, чтобы сохранить постоянство интерфейса при выборе RTL-макета: Arrangement.Absolute
Если вы хотите добавить расстояние между элементами, вы можете использовать такую конструкцию:
Arrangement.spacedBy(5.dp, Alignment.CenterHorizontally)
maxItemsInEachRow можно использовать вместе с модификаторами веса, чтобы сделать что-то вроде этого:
Вес всех кнопок установлен на 1, кроме кнопки «ноль», для которой вес установлен на 2.
FlowRow(maxItemsInEachRow = 4) { buttons.forEach { FlowButton( modifier = Modifier .aspectRatio(1 * it.weight) .clip(CircleShape) .background(it.color) .weight(it.weight), text = it.text, textColor = it.textColor, ) } }
Как видите, в простых примерах композабл FlowRow и FlowColumn очень просты в использовании — они являются мощным и гибким инструментом компоновки для динамических или неизвестных размеров. Это делает их особенно полезными для динамических и отзывчивых интерфейсов, которые адаптируются к различным размерам и ориентации экрана. Мы ожидаем, что приведенные выше примеры покроют потребности большинства разработчиков, но мы все еще хотим создать более сложный пример с использованием этих новых макетов и анимацией переходов, которые могут происходить при добавлении, удалении или изменении положения элементов.