FlowRow и FlowColumn – это функции, похожие на Row и Column, но отличающиеся тем, что элементы переносятся на следующую строку, когда в контейнере заканчивается место. Будет создано несколько строк или столбцов. Количество элементов в строке также можно контролировать, задав значения для параметров maxItemsInEachRow или maxItemsInEachColumn. Часто для создания адаптивных макетов можно использовать FlowRow и FlowColumn. Контент не будет обрезаться, если элементы слишком велики для одного из измерений. Кроме того, сочетание maxItemsInEach* и Modifier.weight(weight) позволяет создавать макеты, которые при необходимости заполняют или расширяют ширину строки или столбца.
Пример использования: чип или интерфейс фильтрации.
FlowRowКак пользоваться отчетом
Чтобы использовать FlowRow или FlowColumn, создайте эти функции и поместите в них элементы, которые должны следовать стандартному потоку:
@Composable private fun FlowRowSimpleUsageExample() { FlowRow(modifier = Modifier.padding(8.dp)) { ChipItem("Price: High to Low") ChipItem("Avg rating: 4+") ChipItem("Free breakfast") ChipItem("Free cancellation") ChipItem("£50 pn") } }
Этот фрагмент кода приводит к появлению интерфейса, показанного выше, в котором элементы автоматически переносятся на следующую строку, когда в первой строке заканчивается место.
Особенности макета с перетеканием
В макетах с автоматическим размещением есть следующие функции и свойства, которые можно использовать для создания различных макетов в приложении.
Расположение по главной оси: горизонтальное или вертикальное расположение.
Главная ось – это ось, вдоль которой располагаются элементы (например, в FlowRow элементы размещаются по горизонтали). Параметр horizontalArrangement в FlowRow определяет, как свободное пространство распределяется между элементами.
В таблице ниже приведены примеры того, как задать значение параметра horizontalArrangement для объектов, относящихся к параметру FlowRow:
Горизонтальное расположение задано на |
Результат |
|
|
|
|
|
|
|
|
|
|
|
Для FlowColumn доступны похожие варианты с verticalArrangement, по умолчанию используется Arrangement.Top.
Расположение по поперечной оси
Поперечная ось – это ось, перпендикулярная главной. Например, на изображении FlowRow это вертикальная ось. Чтобы изменить способ расположения содержимого контейнера на поперечной оси, используйте свойство verticalArrangement для FlowRow и horizontalArrangement для FlowColumn.
В таблице ниже приведены примеры того, как задавать разные значения параметра verticalArrangement для объектов с помощью параметра FlowRow.
Вертикальное расположение на устройстве |
Результат |
|
|
|
|
|
Для FlowColumn доступны похожие варианты с horizontalArrangement.
По умолчанию используется значение Arrangement.Start.
Выравнивание отдельных объектов
Вы можете выровнять отдельные элементы в строке по-разному. Это отличается от verticalArrangement и horizontalArrangement, поскольку выравнивает элементы в пределах текущей строки. Вы можете применить его с помощью метода Modifier.align().
Например, если в контейнере FlowRow элементы имеют разную высоту, строка принимает высоту самого большого элемента и применяет Modifier.align(alignmentOption) к элементам:
Вертикальное выравнивание установлено на |
Результат |
|
|
|
|
|
Для FlowColumn доступны похожие варианты. По умолчанию используется выравнивание Alignment.Start.
Максимальное количество элементов в строке или столбце
Параметры maxItemsInEachRow или maxItemsInEachColumn определяют максимальное количество элементов на главной оси, которое может быть в одной строке до переноса на следующую. По умолчанию установлено значение Int.MAX_INT, которое позволяет размещать как можно больше элементов, если их размеры позволяют им поместиться в строке.
Например, если задать значение maxItemsInEachRow, то в начальном макете будет только три элемента:
Максимальное значение не задано |
|
|
|
Вес товаров
Вес увеличивает размер объекта в зависимости от его коэффициента и доступного места в строке, в которой он был размещен. Важно отметить, что между FlowRow и Row есть разница в том, как веса используются для расчета ширины элемента. Для Rows вес рассчитывается на основе всех товаров в Row. В случае с FlowRow вес определяется на основе элементов в строке, в которую помещен элемент, а не всех элементов в контейнере FlowRow.
Например, если у вас есть четыре объекта, расположенных на одной линии, и их
веса составляют 1f, 2f, 1f, 3f, то общий вес будет равен 7f. Оставшееся в строке или столбце пространство будет разделено на 7f. Ширина каждого товара будет рассчитана по формуле: weight * (remainingSpace / totalWeight).
Вы можете использовать сочетание Modifier.weight и max items с FlowRow или FlowColumn, чтобы создать макет в виде сетки. Этот подход полезен для создания адаптивных макетов, которые подстраиваются под размер экрана устройства.
Ниже приведены примеры того, как можно использовать веса. Например, это может быть сетка с элементами одинакового размера, как показано ниже:
FlowRowЧтобы создать сетку с одинаковыми размерами объектов, выполните следующие действия:
val rows = 3 val columns = 3 FlowRow( modifier = Modifier.padding(4.dp), horizontalArrangement = Arrangement.spacedBy(4.dp), maxItemsInEachRow = rows ) { val itemModifier = Modifier .padding(4.dp) .height(80.dp) .weight(1f) .clip(RoundedCornerShape(8.dp)) .background(MaterialColors.Blue200) repeat(rows * columns) { Spacer(modifier = itemModifier) } }
Важно отметить, что если вы добавите ещё один элемент и повторите его 10 раз вместо 9, то последний элемент займет весь последний столбец, поскольку общий вес для всей строки будет равен 1f:
FlowRow, чтобы последний элемент занимал всю ширинуВеса можно сочетать с другими функциями Modifiers, например Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio) или Modifier.fillMaxWidth(fraction). Все эти модификаторы работают вместе, чтобы обеспечить адаптивный размер элементов в контейнере FlowRow (или FlowColumn).
Вы также можете создать чередующуюся сетку из объектов разных размеров, в которой два объекта занимают половину ширины, а один – всю ширину следующего столбца:
FlowRow с чередующимися размерами строкДля этого используйте следующий код:
FlowRow( modifier = Modifier.padding(4.dp), horizontalArrangement = Arrangement.spacedBy(4.dp), maxItemsInEachRow = 2 ) { val itemModifier = Modifier .padding(4.dp) .height(80.dp) .clip(RoundedCornerShape(8.dp)) .background(Color.Blue) repeat(6) { item -> // if the item is the third item, don't use weight modifier, but rather fillMaxWidth if ((item + 1) % 3 == 0) { Spacer(modifier = itemModifier.fillMaxWidth()) } else { Spacer(modifier = itemModifier.weight(0.5f)) } } }
Дробные размеры
С помощью атрибута "размер" Modifier.fillMaxWidth(fraction) можно указать размер контейнера, в котором должен находиться товар. Это отличается от того, как работает параметр Modifier.fillMaxWidth(fraction) при применении к элементам Row или Column, поскольку элементы Row/Column занимают процент оставшейся ширины, а не всю ширину контейнера.
Например, следующий код дает разные результаты при использовании FlowRow и Row:
FlowRow( modifier = Modifier.padding(4.dp), horizontalArrangement = Arrangement.spacedBy(4.dp), maxItemsInEachRow = 3 ) { val itemModifier = Modifier .clip(RoundedCornerShape(8.dp)) Box( modifier = itemModifier .height(200.dp) .width(60.dp) .background(Color.Red) ) Box( modifier = itemModifier .height(200.dp) .fillMaxWidth(0.7f) .background(Color.Blue) ) Box( modifier = itemModifier .height(200.dp) .weight(1f) .background(Color.Magenta) ) }
|
|
|
|
fillMaxColumnWidth() и fillMaxRowHeight()
Применение Modifier.fillMaxColumnWidth() или Modifier.fillMaxRowHeight() к элементу внутри FlowColumn или FlowRow
гарантирует, что элементы в том же столбце или строке будут иметь ту же ширину или высоту, что и самый большой элемент в столбце или строке.
Например, в этом примере с помощью FlowColumn показывается список десертов Android. Вы можете увидеть разницу в ширине каждого элемента, когда к элементам применяется Modifier.fillMaxColumnWidth(), и когда это не так, а элементы переносятся.
FlowColumn( Modifier .padding(20.dp) .fillMaxHeight() .fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp), verticalArrangement = Arrangement.spacedBy(8.dp), maxItemsInEachColumn = 5, ) { repeat(listDesserts.size) { Box( Modifier .fillMaxColumnWidth() .border(1.dp, Color.DarkGray, RoundedCornerShape(8.dp)) .padding(8.dp) ) { Text( text = listDesserts[it], fontSize = 18.sp, modifier = Modifier.padding(3.dp) ) } } }
Свойство |
|
Ширина не меняется (элементы переносятся) |
|
Рекомендуем
- Примечание. Текст ссылки показывается, когда JavaScript отключен.
- Основные сведения о макетах в Compose
- ConstraintLayout в Compose
- Действия редактора {:#editor-actions}