FlowRow と FlowColumn は、Row と Column に似たコンポーザブルですが、コンテナのスペースがなくなると、アイテムが次の行に流れる点が異なります。これにより、複数の行または列が作成されます。1 行のアイテム数は、maxItemsInEachRow または maxItemsInEachColumn を設定して制御することもできます。多くの場合、FlowRow と FlowColumn を使用してレスポンシブ レイアウトを構築できます。アイテムが大きすぎて 1 つのディメンションに収まらない場合でも、コンテンツが切り取られることはありません。また、maxItemsInEach* と Modifier.weight(weight) を組み合わせて使用すると、必要に応じて行または列の幅を埋める/拡張するレイアウトを構築できます。
一般的な例は、チップまたはフィルタリング UI です。
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") } }
このスニペットの結果、上記の 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 です。これにより、サイズが許す限り、できるだけ多くのアイテムを 1 行に収めることができます。
たとえば、maxItemsInEachRow を設定すると、初期レイアウトに 3 つのアイテムのみが強制的に配置されます。
最大値が設定されていません |
|
|
|
アイテムの重み
weight は、その係数と、配置された行の利用可能なスペースに基づいてアイテムを拡大します。重要なのは、FlowRow と Row では、重みを使用してアイテムの幅を計算する方法が異なる点です。Rows の場合、重みは Row のすべてのアイテムに基づきます。FlowRow の場合、重みは FlowRow コンテナ内のすべてのアイテムではなく、アイテムが配置されている行のアイテムに基づきます。
たとえば、1 つの行に 4 つのアイテムがあり、それぞれに 1f, 2f, 1f と 3f の異なる重みが設定されている場合、合計の重みは 7f になります。行または列の残りのスペースは 7f で分割されます。各アイテムの幅は、weight * (remainingSpace / totalWeight) を使用して計算されます。
Modifier.weight と最大アイテム数を 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) } }
重要な点として、別のアイテムを追加して 9 回ではなく 10 回繰り返すと、行全体の合計ウェイトが 1f になるため、最後のアイテムが最後の列全体を占有します。
FlowRow を使用して、最後のアイテムが全幅を占めるグリッドを作成する重みは、Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio) や Modifier.fillMaxWidth(fraction) などの他の Modifiers と組み合わせることができます。これらの修飾子はすべて連携して、FlowRow(または FlowColumn)内のアイテムのレスポンシブなサイズ変更を可能にします。
また、異なるアイテムサイズを交互に配置するグリッドを作成することもできます。このグリッドでは、2 つのアイテムがそれぞれ幅の半分を占め、1 つのアイテムが次の列の幅全体を占めます。
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()
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}