FlowRow
と FlowColumn
は Row
と Column
に類似していますが、コンテナのスペースが不足するとアイテムが次の行に移るという点で異なります。これにより、複数の行または列が作成されます。maxItemsInEachRow
または maxItemsInEachColumn
を設定して、行内のアイテム数も制御できます。多くの場合、FlowRow
と FlowColumn
を使用してレスポンシブ レイアウトを作成できます。1 つのディメンションに対してアイテムが大きすぎる場合でもコンテンツが切り取られることはありません。また、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
は、次の行に折り返す前に 1 行で許容する主軸のアイテムの最大数を定義します。デフォルトは 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 つのアイテムがすべて 1 つの行に配置され、それぞれ重みが異なる 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) } }
重要な点として、別のアイテムを追加してそれを 9 回ではなく 10 回繰り返すと、行全体の重みの合計は 1f
になるため、最後のアイテムが最後の列全体を占有します。
重みは、Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio)
や Modifier.fillMaxWidth(fraction)
などの他の Modifiers
と組み合わせることができます。これらの修飾子はすべて連携して機能し、FlowRow
(または FlowColumn
)内のアイテムのサイズをレスポンシブにできます。
異なるアイテムサイズのグリッドを交互に作成することもできます。その場合、2 つのアイテムの幅の半分をそれぞれ占め、1 つのアイテムは次の列の幅いっぱいに表示します。
これは次のコードで実現できます。
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()
FlowColumn
または FlowRow
内のアイテムに Modifier.fillMaxColumnWidth()
または Modifier.fillMaxRowHeight()
を適用すると、同じ列または行のアイテムが、その列または行の最も大きなアイテムと同じ幅または高さになります。
たとえば、次の例では 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}