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
.
Для FlowRow
в следующей таблице показаны примеры установки различных verticalArrangement
для элементов:
Вертикальное расположение установлено на | Результат |
| ![]() |
![]() | |
![]() |
Для FlowColumn
аналогичные параметры доступны с horizontalArrangement
. По умолчанию поперечная ось расположена по-умолчанию Arrangement.Start
.
Индивидуальное выравнивание элементов
Вы можете захотеть расположить отдельные элементы в строке с разным выравниванием. Это отличается от verticalArrangement
и horizontalArrangement
, поскольку выравнивает элементы в текущей строке . Вы можете применить это с помощью Modifier.align()
.
Например, если элементы в FlowRow
имеют разную высоту, строка берет высоту самого большого элемента и применяет Modifier.align(alignmentOption)
к элементам:
Вертикальное выравнивание установлено на | Результат |
| ![]() |
![]() | |
![]() |
Для FlowColumn
доступны аналогичные параметры. Выравнивание по умолчанию — Alignment.Start
.
Максимальное количество элементов в строке или столбце
Параметры maxItemsInEachRow
или maxItemsInEachColumn
определяют максимальное количество элементов на главной оси, которые можно разместить в одной строке перед переносом на следующую. Значение по умолчанию — Int.MAX_INT
, что позволяет размещать как можно больше элементов, если их размеры позволяют им помещаться в строку.
Например, установка maxItemsInEachRow
заставит исходный макет содержать только 3 элемента:
Максимальное значение не установлено | |
![]() | ![]() |
Вес товара
Weight увеличивает элемент на основе его коэффициента и доступного пространства на строке, в которую он был помещен. Важно отметить, что существует разница между FlowRow
и Row
в том, как веса используются для расчета ширины элемента. Для Rows
вес основан на всех элементах в Row
. С FlowRow
вес основан на элементах в строке, в которую помещен элемент , а не на всех элементах в контейнере FlowRow
.
Например, если у вас есть 4 элемента, которые все попадают в линию, каждый с разным весом 1f, 2f, 1f
и 3f
, общий вес составляет 7f
. Оставшееся пространство в строке или столбце будет разделено на 7f
. Затем ширина каждого элемента будет рассчитана с помощью: weight * (remainingSpace / totalWeight)
.
Вы можете использовать комбинацию Modifier.weight
и max элементов с 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 отключен.
- Основы создания макета
- ConstraintLayout в Compose
- Действия редактора {:#editor-actions}