FlowRow
und FlowColumn
sind Elemente, die Row
und Column
ähneln, sich aber dadurch unterscheiden, dass Elemente in die nächste Zeile fließen, wenn im Container kein Platz mehr vorhanden ist. Dadurch werden mehrere Zeilen oder Spalten erstellt. Die Anzahl der Elemente in einer Zeile kann auch durch Festlegen von maxItemsInEachRow
oder maxItemsInEachColumn
gesteuert werden. Mit FlowRow
und FlowColumn
lassen sich oft responsive Layouts erstellen. Inhalte werden nicht abgeschnitten, wenn Elemente für eine Dimension zu groß sind. Mit einer Kombination aus maxItemsInEach*
und Modifier.weight(weight)
können Sie Layouts erstellen, die bei Bedarf die Breite einer Zeile oder Spalte füllen oder maximieren.
Ein typisches Beispiel ist eine Chip- oder Filteroberfläche:
Grundlegende Nutzung
Wenn du FlowRow
oder FlowColumn
verwenden möchtest, erstelle diese Composeables und platziere die Elemente darin, die dem Standardablauf folgen sollen:
@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") } }
Dieses Snippet führt zur oben gezeigten Benutzeroberfläche, bei der Elemente automatisch in die nächste Zeile verschoben werden, wenn in der ersten Zeile kein Platz mehr vorhanden ist.
Merkmale des Flusslayouts
Flow-Layouts haben die folgenden Funktionen und Eigenschaften, mit denen Sie verschiedene Layouts in Ihrer App erstellen können.
Anordnung der Hauptachse: horizontal oder vertikal
Die Hauptachse ist die Achse, auf der Elemente angeordnet werden. In FlowRow
sind Elemente beispielsweise horizontal angeordnet. Mit dem Parameter horizontalArrangement
in FlowRow
wird festgelegt, wie der kostenlose Speicherplatz zwischen den Elementen verteilt wird.
Die folgende Tabelle zeigt Beispiele für die Festlegung von horizontalArrangement
für Elemente für FlowRow
:
Horizontale Anordnung auf |
Ergebnis |
|
|
Für FlowColumn
sind ähnliche Optionen mit verticalArrangement
verfügbar, wobei Arrangement.Top
die Standardeinstellung ist.
Querachsenanordnung
Die Querachse ist die Achse in der entgegengesetzten Richtung zur Hauptachse. In FlowRow
ist dies beispielsweise die vertikale Achse. Wenn Sie ändern möchten, wie der gesamte Inhalt im Container in der Querachse angeordnet wird, verwenden Sie verticalArrangement
für FlowRow
und horizontalArrangement
für FlowColumn
.
In der folgenden Tabelle sind Beispiele für die Festlegung verschiedener verticalArrangement
für die Elemente zu sehen:FlowRow
Vertikale Anordnung auf |
Ergebnis |
|
|
Für FlowColumn
sind ähnliche Optionen mit horizontalArrangement
verfügbar.
Die Standardanordnung der Querachsen ist Arrangement.Start
.
Ausrichtung einzelner Artikel
Sie können einzelne Elemente innerhalb der Zeile mit unterschiedlichen Ausrichtungen positionieren. Das unterscheidet sich von verticalArrangement
und horizontalArrangement
, da die Elemente innerhalb der aktuellen Zeile ausgerichtet werden. Das können Sie mit Modifier.align()
tun.
Wenn Elemente in einer FlowRow
beispielsweise unterschiedliche Höhen haben, wird für die Zeile die Höhe des größten Elements übernommen und Modifier.align(alignmentOption)
auf die Elemente angewendet:
Vertikale Ausrichtung auf |
Ergebnis |
|
|
Für FlowColumn
sind ähnliche Optionen verfügbar. Die Standardausrichtung ist Alignment.Start
.
Maximale Anzahl von Elementen in Zeile oder Spalte
Mit den Parametern maxItemsInEachRow
oder maxItemsInEachColumn
wird die maximale Anzahl der Elemente in der Hauptachse definiert, die in einer Zeile zulässig sind, bevor der Text auf die nächste Zeile umgebrochen wird. Die Standardeinstellung ist Int.MAX_INT
. Damit sind so viele Elemente wie möglich zulässig, sofern sie in die Zeile passen.
Wenn Sie beispielsweise ein maxItemsInEachRow
festlegen, hat das ursprüngliche Layout nur drei Elemente:
Kein Maximum festgelegt |
|
Lazy Loading-Ablaufelemente
ContextualFlowRow
und ContextualFlowColumn
sind eine spezielle Version von FlowRow
und FlowColumn
, mit der Sie den Inhalt Ihrer Flusszeile oder ‑spalte per Lazy Load laden können. Sie liefern auch Informationen zur Position der Elemente (Index, Zeilennummer und verfügbare Größe), z. B. ob sich das Element in der ersten Zeile befindet. Das ist nützlich bei großen Datenmengen und wenn Sie Kontextinformationen zu einem Element benötigen.
Der Parameter maxLines
begrenzt die Anzahl der angezeigten Zeilen und der Parameter overflow
gibt an, was angezeigt werden soll, wenn ein Überlauf von Elementen erreicht wird. So können Sie einen benutzerdefinierten Wert für expandIndicator
oder collapseIndicator
angeben.
So blenden Sie beispielsweise die Schaltfläche „+ (Anzahl der verbleibenden Artikel)“ oder „Weniger anzeigen“ ein:
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") }
Artikelgewichte
Mit dem Gewicht wird ein Element basierend auf seinem Faktor und dem verfügbaren Platz in der Zeile, in der es platziert wurde, vergrößert. Ein wichtiger Unterschied zwischen FlowRow
und Row
besteht darin, wie Gewichte zur Berechnung der Breite eines Elements verwendet werden. Bei Rows
basiert die Gewichtung auf allen Artikeln im Row
. Bei FlowRow
basiert die Gewichtung auf den Elementen der Werbebuchung, in der ein Element platziert wird, und nicht auf allen Elementen im Container FlowRow
.
Beispiel: Wenn Sie vier Elemente haben, die alle auf eine Linie fallen und jeweils eine unterschiedliche Gewichtung von 1f, 2f, 1f
und 3f
haben, beträgt die Gesamtgewichtung 7f
. Der verbleibende Platz in einer Zeile oder Spalte wird durch 7f
geteilt. Die Breite der einzelnen Artikel wird dann mit folgender Formel berechnet: weight * (remainingSpace / totalWeight)
.
Sie können eine Kombination aus Modifier.weight
- und Max-Elementen mit FlowRow
oder FlowColumn
verwenden, um ein gitterartiges Layout zu erstellen. Dieser Ansatz eignet sich zum Erstellen responsiver Layouts, die sich an die Größe Ihres Geräts anpassen.
Es gibt einige Beispiele dafür, was Sie mit Gewichten erreichen können. Ein Beispiel ist ein Raster, in dem die Elemente gleich groß sind, wie unten dargestellt:
So erstellen Sie ein Raster mit gleich großen Elementen:
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) } }
Wenn Sie einen weiteren Artikel hinzufügen und ihn zehn statt neunmal wiederholen, nimmt der letzte Artikel die gesamte letzte Spalte ein, da das Gesamtgewicht für die gesamte Zeile 1f
beträgt:
Sie können Gewichte mit anderen Modifiers
kombinieren, z. B. mit Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio)
oder Modifier.fillMaxWidth(fraction)
. Diese Modifikatoren wirken zusammen, um eine responsive Größe von Elementen innerhalb einer FlowRow
(oder FlowColumn
) zu ermöglichen.
Sie können auch ein abwechselndes Raster mit unterschiedlichen Elementgrößen erstellen, wobei zwei Elemente jeweils die Hälfte der Breite einnehmen und ein Element die volle Breite der nächsten Spalte einnimmt:
Das geht mit dem folgenden Code:
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)) } } }
Bruchteilmäßige Größenanpassung
Mit Modifier.fillMaxWidth(fraction)
können Sie die Größe des Containers angeben, den ein Element einnehmen soll. Das unterscheidet sich von der Funktionsweise von Modifier.fillMaxWidth(fraction)
, wenn es auf Row
oder Column
angewendet wird, da Row/Column
-Elemente einen Prozentsatz der verbleibenden Breite einnehmen, anstatt die gesamte Breite des Containers.
Der folgende Code liefert beispielsweise unterschiedliche Ergebnisse, wenn FlowRow
oder Row
verwendet wird:
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()
und fillMaxRowHeight()
Wenn Sie Modifier.fillMaxColumnWidth()
oder Modifier.fillMaxRowHeight()
auf ein Element in einem FlowColumn
oder FlowRow
anwenden, haben alle Elemente in derselben Spalte oder Zeile dieselbe Breite oder Höhe wie das größte Element in der Spalte oder Zeile.
In diesem Beispiel wird FlowColumn
beispielsweise verwendet, um die Liste der Android-Desserts anzuzeigen. Sie sehen den Unterschied in der Breite der einzelnen Elemente, wenn Modifier.fillMaxColumnWidth()
auf die Elemente angewendet wird, und wenn die Elemente umgebrochen werden.
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) ) } } }
|
|
Es wurden keine Änderungen an der Breite festgelegt (Elemente werden umgebrochen) |
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Grundlagen des Layouts
- ConstraintLayout in Compose
- Aktionen im Editor {:#editor-actions}