FlowRow
和FlowColumn
是与 Row
和 Column
类似但项有所不同的可组合项
当容器耗尽空间时,流向下一行。这会创建
多行或多列。还可以控制一行中项目的数量
只需设置 maxItemsInEachRow
或 maxItemsInEachColumn
即可。您通常可以使用
FlowRow
和 FlowColumn
,用于构建响应式布局 - 内容不会被剪切
如果项对于某个维度而言过大,并且同时使用
将 maxItemsInEach*
与 Modifier.weight(weight)
搭配使用有助于构建符合以下条件的布局:
根据需要填充/展开行或列的宽度。
典型示例是条状标签或过滤界面:
基本用法
如需使用 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 项:
未设置上限 |
|
延迟加载流项
ContextualFlowRow
和 ContextualFlowColumn
是
FlowRow
和 FlowColumn
的版本,可让您延迟加载内容
数据流行或列的位置。还可以提供有关商品位置的信息
(索引、行号和可用大小),例如,如果项位于第一个
。这对于大型数据集和上下文信息非常有用
。
maxLines
参数会限制显示的行数,overflow
参数指定在发生商品溢出时应显示的内容
从而允许您指定自定义expandIndicator
或
collapseIndicator
。
例如,要显示“+”(剩余项目数)或“收起”按钮:
val totalCount = 40 var maxLines by remember { mutableStateOf(2) } val moreOrCollapseIndicator = @Composable { scope: ContextualFlowRowOverflowScope -> val remainingItems = totalCount - scope.shownItemCount ChipItem(if (remainingItems == 0) "Less" else "+$remainingItems", onClick = { if (remainingItems == 0) { maxLines = 2 } else { maxLines += 5 } }) } ContextualFlowRow( modifier = Modifier .safeDrawingPadding() .fillMaxWidth(1f) .padding(16.dp) .wrapContentHeight(align = Alignment.Top) .verticalScroll(rememberScrollState()), verticalArrangement = Arrangement.spacedBy(4.dp), horizontalArrangement = Arrangement.spacedBy(8.dp), maxLines = maxLines, overflow = ContextualFlowRowOverflow.expandOrCollapseIndicator( minRowsToShowCollapse = 4, expandIndicator = moreOrCollapseIndicator, collapseIndicator = moreOrCollapseIndicator ), itemCount = totalCount ) { index -> ChipItem("Item $index") }
商品重量
权重可根据项的系数和行的可用空间增加项
。重要的是,FlowRow
和 Row
之间有差异
以及如何使用权重计算物品的宽度。对于 Rows
,权重
基于 Row
中的所有项。使用 FlowRow
时,权重基于
包含某个项的专列项中的,而不是
FlowRow
容器。
例如,如果您有 4 个项目,它们全都在同一行上,并且每个项目都有不同的
分别为 1f, 2f, 1f
和 3f
,总权重为 7f
。剩余空间
将除以 7f
。然后,每个列表项的宽度
计算公式为:weight * (remainingSpace / totalWeight)
。
您可以将 Modifier.weight
和商品数上限功能与 FlowRow
或
FlowColumn
创建类似于网格的布局。这种方法有助于创建
可适应设备尺寸的自适应布局。
下面通过几个不同的示例说明了使用权重可以实现的效果。一个 示例是一个网格,其中各项大小均等,如下所示:
如需创建内容大小相同的网格,您可以执行以下操作:
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
:
您可以将权重与其他 Modifiers
结合使用,例如
Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio)
,或者
Modifier.fillMaxWidth(fraction)
。这些修饰符都与
支持对 FlowRow
(或 FlowColumn
)内的项进行自适应大小调整。
您还可以创建一个大小不同的交替网格,其中两个项目 每个元素占总宽度的一半,并且一个元素占下一个项目的全宽 列:
您可以使用以下代码实现这一目的:
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 布局基础知识
- Compose 中的 ConstraintLayout
- 编辑器操作 {:#editor-actions}