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 とは異なります。これは Modifier.align() で適用できます。

たとえば、FlowRow 内のアイテムの高さが異なる場合、その行は 最も大きなアイテムの高さです。指定されたアイテムに Modifier.align(alignmentOption) を items:

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

結果

Alignment.TopDefault

アイテムを上部に揃えました

Alignment.Bottom

アイテムを下揃えにしました

Alignment.CenterVertically

アイテムを中央に揃えました

FlowColumn についても、同様のオプションを使用できます。デフォルトのアライメントは、 Alignment.Start

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

パラメータ maxItemsInEachRow または maxItemsInEachColumn は、メイン軸で 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 を使用してグリッドを作成し、最後のアイテムが全幅を占めるようにする

重みは、Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio)Modifier.fillMaxWidth(fraction) などの他の Modifiers と組み合わせることができます。これらの修飾子はすべて 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

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

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