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 の場合:

FlowRow に水平配置を設定しました

結果

Arrangement.StartDefault

開始時に配置されたアイテム数

Arrangement.SpaceBetween

間にスペースを空けたアイテム配置

Arrangement.Center

中央に配置されたアイテム

Arrangement.End

項目を最後に配置

Arrangement.SpaceAround

周囲にスペースを置いて整理されたアイテム

Arrangement.spacedBy(8.dp)

特定の dp 間隔のアイテム

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) を items:

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)

FlowRow で、Modifier.weight と最大アイテム数を組み合わせて使用できます。または、 FlowColumn: グリッドのようなレイアウトを作成します。このアプローチは、 デバイスのサイズに合わせて調整できるレスポンシブ レイアウトです。

重みを使用して実現できることの例はいくつかあります。1 本 は、以下のようにアイテムのサイズが同じグリッドです。

フロー行でグリッドを作成しました
図 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 分の 1 である中央のアイテム。

小数の幅とフロー行

Row: 中央のアイテムが Row の残りの幅の 0.7% を占めています。

小数の幅(行あり)

fillMaxColumnWidth()fillMaxRowHeight()

Modifier.fillMaxColumnWidth() または FlowColumn または FlowRow 内のアイテムへの 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

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

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