Ablauflayouts in Compose

FlowRow und FlowColumn sind zusammensetzbare Funktionen, die Row und Column ähneln, sich jedoch darin unterscheiden, dass sie sich in diesen Elementen unterscheiden. in die nächste Zeile fließen, wenn der Platz knapp wird. Dadurch entstehen Zeilen oder Spalten enthält. Die Anzahl der Elemente in einer Zeile kann auch indem Sie maxItemsInEachRow oder maxItemsInEachColumn festlegen. Sie können häufig FlowRow und FlowColumn zum Erstellen responsiver Layouts – die Inhalte werden nicht ausgeschnitten wenn Artikel zu groß für eine Dimension sind, und wenn Sie eine Kombination maxItemsInEach* mit Modifier.weight(weight) kann Ihnen helfen, Layouts zu erstellen, die Breite einer Zeile oder Spalte bei Bedarf ausfüllen/erweitern können.

Das typische Beispiel zeigt einen Chip oder eine Filteroberfläche:

<ph type="x-smartling-placeholder">
</ph> 5 Chips in einer FlowRow, die den Überlauf in die nächste Zeile anzeigen, wenn kein
mehr Speicherplatz verfügbar ist.
Abbildung 1: Beispiel für FlowRow

Grundlegende Nutzung

Wenn Sie FlowRow oder FlowColumn verwenden möchten, erstellen Sie diese zusammensetzbaren Funktionen und platzieren Sie die Elemente das dem Standardablauf folgen sollte:

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

Durch dieses Snippet wird die oben gezeigte Benutzeroberfläche angezeigt. Elemente werden automatisch wenn in der ersten Zeile kein Platz mehr ist.

Features des Ablauflayouts

Fluss-Layouts haben die folgenden Funktionen und Eigenschaften, die Sie verwenden können, um verschiedene Layouts in Ihrer App zu erstellen.

Anordnung der Hauptachse: horizontal oder vertikal

Die Hauptachse ist die Achse, auf der Elemente angeordnet werden (z. B. FlowRow, Elemente sind horizontal angeordnet. Das horizontalArrangement in FlowRow steuert, wie freier Speicherplatz auf die Elemente verteilt wird.

Die folgende Tabelle zeigt Beispiele für die Festlegung von horizontalArrangement für Elemente für FlowRow:

Horizontale Anordnung auf FlowRow festgelegt

Ergebnis

Arrangement.Start (Default)

Artikel nach Anfang angeordnet

Arrangement.SpaceBetween

Anordnung von Elementen mit Abstand dazwischen

Arrangement.Center

Artikel in der Mitte angeordnet

Arrangement.End

Elemente am Ende angeordnet

Arrangement.SpaceAround

Gegenstände in um sie herum angeordnetem Platz

Arrangement.spacedBy(8.dp)

Elemente mit einem bestimmten dp-Abstand

Für FlowColumn sind ähnliche Optionen mit verticalArrangement verfügbar, wobei Folgendes gilt: der Standardwert Arrangement.Top.

Querachsenanordnung

Die Querachse ist die Achse in der entgegengesetzten Richtung zur Hauptachse. Für In FlowRow ist das beispielsweise die vertikale Achse. Um zu ändern, wie der Gesamt- sind die Behälter in Querachsen angeordnet, verwenden Sie verticalArrangement für FlowRow und horizontalArrangement für FlowColumn.

In der folgenden Tabelle sehen Sie für FlowRow Beispiele für verticalArrangement für die Artikel:

Vertikale Anordnung auf FlowRow festgelegt

Ergebnis

Arrangement.Top (Default)

Anordnung des Containers oben

Arrangement.Bottom

Behälter Bodenanordnung

Arrangement.Center

Container Center-Anordnung

Für FlowColumn sind ähnliche Optionen mit horizontalArrangement verfügbar. Die Standardanordnung der Querachsen ist Arrangement.Start.

Ausrichtung einzelner Elemente

Sie können einzelne Elemente innerhalb der Zeile mit unterschiedlichen Ausrichtungen. Dies unterscheidet sich von verticalArrangement und horizontalArrangement, indem die Elemente damit an der aktuellen Zeile ausgerichtet werden. Sie können Modifier.align() anwenden.

Wenn beispielsweise Elemente in einem FlowRow unterschiedliche Höhen haben, wird in der Zeile Höhe des größten Elements und wendet Modifier.align(alignmentOption) auf den Wert Elemente:

Vertikale Ausrichtung auf FlowRow festgelegt

Ergebnis

Alignment.Top (Default)

Elemente, die oben ausgerichtet sind

Alignment.Bottom

Elemente unten ausgerichtet

Alignment.CenterVertically

Elemente mittig ausgerichtet

Für FlowColumn sind ähnliche Optionen verfügbar. Die Standardausrichtung ist Alignment.Start

Maximale Anzahl der Elemente in Zeile oder Spalte

Die Parameter maxItemsInEachRow oder maxItemsInEachColumn definieren das Maximum Elemente in der Hauptachse in eine Linie zu lassen, bevor sie in die nächste verschoben werden. Die Der Standardwert ist Int.MAX_INT, womit so viele Elemente wie möglich zugelassen werden, solange sodass sie in die Linie passen.

Wenn Sie beispielsweise einen maxItemsInEachRow festlegen, wird das anfängliche Layout nur auf haben 3 Elemente:

Kein Maximalwert festgelegt

maxItemsInEachRow = 3

Kein Maximalwert für Ablaufzeile festgelegt Maximale Anzahl von Elementen in Ablaufzeile festgelegt

Elemente für Lazy Loading

ContextualFlowRow und ContextualFlowColumn sind spezialisierte Version von FlowRow und FlowColumn, mit denen Sie die Inhalte per Lazy Loading laden können Ihrer Ablaufzeile oder -spalte. Sie enthalten auch Informationen zur Position (Index, Zeilennummer und verfügbare Größe), z. B. wenn sich das Element im ersten Zeile. Dies ist nützlich bei großen Datensätzen und wenn Sie Kontextinformationen benötigen, zu einem Artikel.

Der Parameter maxLines begrenzt die Anzahl der angezeigten Zeilen und der Parameter overflow gibt an, was angezeigt werden soll, wenn ein Artikelüberlauf erreicht haben, sodass Sie einen benutzerdefinierten Wert für expandIndicator oder collapseIndicator.

Um beispielsweise "+ (Anzahl verbleibender Artikel)" anzuzeigen, oder „Weniger anzeigen“ Schaltfläche:

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

<ph type="x-smartling-placeholder">
</ph> Beispiel für kontextbezogene Ablaufzeilen
Abbildung 2: Beispiel für ContextualFlowRow

Artikelgewichte

Die Gewichtung vergrößert ein Element basierend auf seinem Faktor und dem verfügbaren Platz auf der Linie, das es in den einsortiert wurde. Wichtig: Es gibt einen Unterschied zwischen FlowRow und Row mit der Gewichtung zur Berechnung der Breite eines Artikels. Gewichtung für Rows basiert auf allen Artikeln in Row. Bei FlowRow basiert das Gewicht auf dem Elemente der Werbebuchung, in der ein Element platziert wird, nicht alle Elemente im FlowRow-Container.

Wenn Sie z. B. vier Elemente haben, die alle auf eine Linie fallen, die alle einen anderen Gewichtungen von 1f, 2f, 1f und 3f hat, beträgt die Gesamtgewichtung 7f. Der verbleibende Speicherplatz in einer Zeile oder Spalte wird durch 7f geteilt. Dann ist jede Elementbreite mit folgender Formel berechnet: weight * (remainingSpace / totalWeight).

Sie können eine Kombination aus Modifier.weight und maximal zulässigen Elementen mit FlowRow oder FlowColumn, um ein rasterähnliches Layout zu erstellen. Dieser Ansatz ist nützlich, um responsive Layouts, die sich an die Größe Ihres Geräts anpassen.

Es gibt verschiedene Beispiele dafür, was Sie mit Gewichtungen erreichen können. Eins Ein Beispiel ist ein Raster, in dem Elemente die gleiche Größe haben, wie unten dargestellt:

<ph type="x-smartling-placeholder">
</ph> Raster mit Ablaufzeile erstellt
Abbildung 3: Raster mit FlowRow erstellen

So erstellen Sie ein Raster gleicher Artikelgröße:

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

Wichtig: Wenn Sie ein weiteres Element hinzufügen und dieses 10-mal statt 9-mal wiederholen, Das letzte Element nimmt die gesamte letzte Spalte ein, als Gesamtgewichtung für die gesamte Zeile ist 1f:

<ph type="x-smartling-placeholder">
</ph> Letztes Element in Originalgröße im Raster
Abbildung 4: Mit FlowRow ein Raster erstellen, bei dem das letzte Element die volle Breite einnimmt

Du kannst Gewichte mit anderen Modifiers-Elementen kombinieren, z. B. Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio) oder Modifier.fillMaxWidth(fraction) Diese Modifikatoren wirken alle in Verbindung mit Responsive Größenanpassung für Artikel innerhalb eines FlowRow (oder FlowColumn) ist möglich.

Sie können auch ein abwechselndes Raster mit unterschiedlichen Elementgrößen erstellen, in dem zwei Elemente jeweils halb so breit, ein Element nimmt die volle Breite des nächsten ein Spalte:

<ph type="x-smartling-placeholder">
</ph> Sich abwechselndes Raster mit Ablaufzeile
Abbildung 5: FlowRow mit abwechselnder Zeilengröße

Dazu können Sie den folgenden Code verwenden:

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

Teilgrößenanpassung

Mit Modifier.fillMaxWidth(fraction) können Sie die Größe der den ein Artikel aufnehmen sollte. Dies unterscheidet sich von der Modifier.fillMaxWidth(fraction) funktioniert, wenn es auf Row oder Column angewendet wird, in dass Row/Column Elemente einen Prozentsatz der verbleibenden Breite einnehmen, des gesamten Containers aus.

Der folgende Code führt beispielsweise zu anderen Ergebnissen bei der Verwendung von FlowRow. gegen 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: Mittleres Element mit einem 0,7-Anteil der gesamten Containerbreite.

Bruchbreite mit Ablaufzeile

Row: Das mittlere Element nimmt 0,7 % der verbleibenden Breite von Row ein.

Bruchbreite mit Zeile

fillMaxColumnWidth() und fillMaxRowHeight()

Sie wenden entweder Modifier.fillMaxColumnWidth() oder Modifier.fillMaxRowHeight() auf einen Artikel in einem FlowColumn oder FlowRow dass Elemente in derselben Spalte oder Zeile dieselbe Breite oder Höhe einnehmen wie das größte Element in der Spalte/Zeile.

In diesem Beispiel wird z. B. FlowColumn verwendet, um die Liste der Android- Desserts. Sie sehen den Unterschied bei der Breite der einzelnen Elemente, wenn Modifier.fillMaxColumnWidth() wird auf die Elemente angewendet, im Vergleich dazu, wenn dies nicht der Fall ist und die Elemente verpacken.

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() auf jedes Element angewendet

FillMaxColumnWidth

Keine Breitenänderungen festgelegt (Elemente umbrechen)

Keine Spaltenbreite für „Füllung“ festgelegt