Compose の Flow レイアウト

FlowRowFlowColumn は、RowColumn に似たコンポーザブルですが、コンテナのスペースが不足するとアイテムが次の行に流れ込む点が異なります。これにより、 複数の行や列を選択できます1 行内のアイテム数は、maxItemsInEachRow または maxItemsInEachColumn を設定することで制御することもできます。よく使われるのは レスポンシブ レイアウトを作成するための FlowRowFlowColumn - コンテンツは切り取られません 1 つのディメンションに対してアイテムが大きすぎる場合はオフ、また、 maxItemsInEach*Modifier.weight(weight) に置き換えると、 必要に応じて行や列の幅を塗りつぶしたり広げたりできます。

一般的な例としては、チップやフィルタリング UI があります。

FlowRow 内の 5 つのチップ。使用可能なスペースがなくなったときに、次の行にオーバーフローします。
図 1. 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 のように、アイテムは横方向に並べられます。horizontalArrangement FlowRow のパラメータは、アイテム間の空き容量の配分を制御します。

次の表に、アイテムに horizontalArrangement を設定する例を示します。 FlowRow の場合:

FlowColumn の場合、verticalArrangement で同様のオプションを使用できます。 デフォルトは Arrangement.Top です。

軸をまたぐ配置

交差軸は、メイン軸の反対方向の軸です。対象 たとえば、FlowRow では縦軸です。組織全体で コンテナ内のコンテンツは交差軸上に配置されます。 FlowRowverticalArrangementhorizontalArrangementFlowColumn

FlowRow の場合、次の表に、アイテムにさまざまな verticalArrangement を設定する例を示します。

垂直方向の配置が FlowRow に設定されている

結果

Arrangement.TopDefault

コンテナの上部の配置

Arrangement.Bottom

コンテナの下部の配置

Arrangement.Center

コンテナの中央配置

FlowColumn の場合、horizontalArrangement で同様のオプションを使用できます。デフォルトのクロス軸配置は Arrangement.Start です。

個々のアイテムの配置

行内の個々の項目を異なる配置で配置することもできます。これは、項目を現在の行内に配置するため、verticalArrangementhorizontalArrangement とは異なります。Google Chat では Modifier.align() を使用してこれを適用します。

たとえば、FlowRow 内のアイテムの高さが異なる場合、行は最大のアイテムの高さを取り、アイテムに Modifier.align(alignmentOption) を適用します。

FlowRow に垂直方向の配置を設定しました

結果

Alignment.TopDefault

アイテムを上揃え

Alignment.Bottom

アイテムが下揃えになっている

Alignment.CenterVertically

アイテムが中央揃えになっている

FlowColumn には、同様のオプションが用意されています。デフォルトのアライメントは、 Alignment.Start

行または列の最大アイテム数

パラメータ maxItemsInEachRow または maxItemsInEachColumn は、 1 行に 1 つずつ配置してから次の行に移ります。デフォルトは Int.MAX_INT で、サイズが行に収まる限り、できるだけ多くのアイテムを指定できます。

たとえば、maxItemsInEachRow を設定すると、初期レイアウトは強制的に 次の 3 つのアイテムが必要です。

上限なし

maxItemsInEachRow = 3

フロー行に最大値が設定されていません フロー行に設定された最大アイテム数

フローアイテムの遅延読み込み

ContextualFlowRowContextualFlowColumn は、FlowRowFlowColumn の特殊なバージョンで、フロー行または列のコンテンツを遅延読み込みできます。商品アイテムの位置に関する情報も提供します (インデックス、行番号、使用可能なサイズ)。たとえば、アイテムが最初の 選択します。これは、大規模なデータセットの場合や、コンテキスト情報が必要な場合に便利です。 確認しました。

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")
}

コンテキスト フロー行の例。
図 2. ContextualFlowRow の例

アイテムの重量

重み付けは、係数と、配置された行の空きスペースに基づいてアイテムを拡大します。重要な点として、FlowRowRow には違いがあります。 重量を使用してアイテムの幅を計算する方法に関連します。Rows の場合、重み付けは Row 内のすべての項目に基づいています。FlowRow の場合、重み付けは FlowRow コンテナ内のすべてのアイテムではなく、アイテムが配置されている行内のアイテムに基づいて行われます。

たとえば、1 つの行に含まれる 4 つの商品がすべて異なる場合、 1f, 2f, 1f3f の重みがある場合、重みの合計は 7f です。行または列の残りのスペースは 7f で割られます。次に、各アイテムの幅は weight * (remainingSpace / totalWeight) を使用して計算されます。

Modifier.weight と最大アイテムを FlowRow または FlowColumn と組み合わせて、グリッド状のレイアウトを作成できます。このアプローチは、デバイスのサイズに合わせて調整されるレスポンシブ レイアウトを作成する場合に便利です。

重み付けを使用して実現できる効果には、いくつかの例があります。たとえば、次に示すように、アイテムのサイズが同じグリッドがあります。

フロー行でグリッドを作成しました
図 3. 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 になるため、最後の項目が最後の列全体を占有することです。

最後のアイテムがグリッド上にフルサイズで表示されます
図 4. FlowRow を使用して、最後のアイテムが幅全体を占めるグリッドを作成する

重みは次のような他の Modifiers と組み合わせることができます。 Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio)、または Modifier.fillMaxWidth(fraction)。これらの修飾子はすべて FlowRow(または FlowColumn)内のアイテムのサイズをレスポンシブに調整できます。

異なるアイテムサイズの交互のグリッドを作成し、そこに 2 つのアイテムを配置することもできます。 それぞれが半分の幅を占め、1 つのアイテムが次の要素の半分の幅を占めます。 列:

フロー行付きの交互のグリッド
図 5. 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) を使用すると、アイテムが占有するコンテナのサイズを指定できます。これは Google Cloud で 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)
    )
}

FlowRow: コンテナ全体の幅の 0.7 の割合の中央アイテム。

小数の幅とフロー行

Row: 残りの Row 幅の 0.7% を占める中央のアイテム。

小数の幅(行あり)

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)
            )
        }
    }
}

各アイテムに Modifier.fillMaxColumnWidth() を適用しました

fillMaxColumnWidth

幅の変更が設定されていない(アイテムの折り返し)

列の幅を塗りつぶす最大値が設定されていません

現在、おすすめはありません。

Google アカウントにしてください。