FlowRow
和 FlowColumn
是與 Row
和 Column
類似的可組合項,但在容器空間不足時,項目會排入下一行。這項操作會建立多個資料列或資料欄。設定 maxItemsInEachRow
或 maxItemsInEachColumn
也可以控制項目中的項目數量。通常,您可以使用 FlowRow
和 FlowColumn
建立回應式版面配置;如果項目過大,無法截斷內容;將 maxItemsInEach*
與 Modifier.weight(weight)
搭配使用,有助於建構可視需要填入/展開列或欄寬度的版面配置。
常見例子為方塊或篩選 UI:
基本用法
如要使用 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") } }
這個程式碼片段會產生以上 UI 結果,當第一列空間不足時,項目會自動移到下一列。
流程版面配置的特徵
流程版面配置具有下列功能和屬性,可用來在應用程式中建立不同的版面配置。
線軸排列方式:水平或垂直排列
主軸是項目配置的軸 (例如在 FlowRow
中,項目會水平排列)。FlowRow
中的 horizontalArrangement
參數可控制各項目之間可用空間的方式分配方式。
下表舉例說明如何為 FlowRow
的項目設定 horizontalArrangement
:
已設定 |
結果 |
|
|
如果是 FlowColumn
,verticalArrangement
也提供類似選項,預設值為 Arrangement.Top
。
跨軸排列
交叉軸是與主軸相反方向的軸。舉例來說,在 FlowRow
中,這是指縱軸。如要變更容器內整體內容在交叉軸上的排列方式,請針對 FlowRow
使用 verticalArrangement
,針對 FlowColumn
使用 horizontalArrangement
。
對於 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)
指定項目應佔用的容器大小。這與套用至 Row
或 Column
時 Modifier.fillMaxWidth(fraction)
的運作方式不同,因為 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}