FlowRow
und FlowColumn
sind zusammensetzbare Funktionen, die Row
und Column
ähneln, sich jedoch dadurch unterscheiden, dass Elemente in die nächste Zeile übergehen, wenn der Speicherplatz des Containers ausgeht. Dadurch werden mehrere Zeilen oder Spalten erstellt. Die Anzahl der Elemente in einer Zeile kann auch durch Festlegen von maxItemsInEachRow
oder maxItemsInEachColumn
gesteuert werden. Häufig können Sie FlowRow
und FlowColumn
zum Erstellen responsiver Layouts verwenden. Inhalte werden nicht abgeschnitten, wenn Elemente zu groß für eine Dimension sind. Wenn Sie eine Kombination aus maxItemsInEach*
und Modifier.weight(weight)
verwenden, können Layouts erstellt werden, bei denen die Breite einer Zeile oder Spalte bei Bedarf ausgefüllt oder erweitert wird.
Das typische Beispiel ist für einen Chip oder eine Filter-UI:
Grundlegende Verwendung
Um FlowRow
oder FlowColumn
zu verwenden, erstellen Sie diese zusammensetzbaren Funktionen und platzieren Sie die Elemente darin. Diese sollten dem Standardablauf folgen:
@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, in der Elemente automatisch in die nächste Zeile fließen, wenn in der ersten Zeile kein Platz mehr vorhanden ist.
Features des Flusslayouts
Ablauflayouts haben die folgenden Funktionen und Eigenschaften, mit denen Sie verschiedene Layouts in Ihrer Anwendung erstellen können.
Anordnung der Hauptachse: horizontal oder vertikal angeordnet
Die Hauptachse ist die Achse, auf der Elemente angeordnet sind. In FlowRow
sind Elemente beispielsweise horizontal angeordnet. Mit dem Parameter horizontalArrangement
in FlowRow
wird gesteuert, wie der kostenlose Speicherplatz auf die Elemente aufgeteilt wird.
Die folgende Tabelle zeigt Beispiele für das Festlegen von horizontalArrangement
für Elemente für FlowRow
:
Horizontale Anordnung für |
Ergebnis |
|
|
Für FlowColumn
sind ähnliche Optionen mit verticalArrangement
verfügbar. Der Standardwert ist Arrangement.Top
.
Kreuzachsenanordnung
Die Kreuzachse ist die Achse, die der Hauptachse entgegengesetzt ist. In FlowRow
ist dies beispielsweise die vertikale Achse. Wenn Sie ändern möchten, wie der Gesamtinhalt innerhalb des Containers in der Kreuzachse angeordnet wird, verwenden Sie verticalArrangement
für FlowRow
und horizontalArrangement
für FlowColumn
.
Die folgende Tabelle zeigt Beispiele für das Festlegen verschiedener verticalArrangement
für die Elemente für FlowRow
:
Vertikale Anordnung auf |
Ergebnis |
|
|
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 positionieren. Dieser Unterschied unterscheidet sich von verticalArrangement
und horizontalArrangement
, da hier die Elemente innerhalb der aktuellen Zeile ausgerichtet werden. Sie können dies mit Modifier.align()
anwenden.
Wenn beispielsweise Elemente in einem FlowRow
unterschiedliche Höhen haben, wird in der Zeile die Höhe des größten Elements verwendet und Modifier.align(alignmentOption)
wird 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
Die Parameter maxItemsInEachRow
oder maxItemsInEachColumn
definieren die maximale Anzahl von Elementen auf der Hauptachse, die in einer Zeile zulässig sind, bevor in die nächste Zeile umgebrochen wird. Die Standardeinstellung ist Int.MAX_INT
. Damit sind so viele Elemente wie möglich zulässig, solange sie in die Zeile passen.
Wenn Sie beispielsweise maxItemsInEachRow
festlegen, hat das anfängliche Layout nur drei Elemente:
Kein Höchstwert festgelegt |
|
Lazy Loading von Elementen
ContextualFlowRow
und ContextualFlowColumn
sind eine spezielle Version von FlowRow
und FlowColumn
, mit der Sie den Inhalt einer Zeile oder Spalte eines Ablaufs per Lazy Loading laden können. Sie liefern auch Informationen zur Position des Elements (Index, Zeilennummer und verfügbare Größe), z. B. ob sich das Element in der ersten Zeile befindet. Dies ist nützlich bei großen Datasets und wenn Sie Kontextinformationen zu einem Element benötigen.
Der Parameter maxLines
begrenzt die Anzahl der angezeigten Zeilen. Der Parameter overflow
gibt an, was angezeigt werden soll, wenn ein Überlauf von Elementen erreicht wird. So können Sie einen benutzerdefinierten expandIndicator
- oder collapseIndicator
-Wert angeben.
So können Sie beispielsweise die Schaltfläche „+ (Anzahl der verbleibenden Elemente)“ oder „Weniger anzeigen“ anzeigen lassen:
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 der Gewichtung vergrößern Sie ein Element basierend auf seinem Faktor und dem verfügbaren Platz auf der Linie, in der es platziert wurde. Wichtig: Bei der Berechnung der Breite eines Artikels anhand der Gewichtung gibt es einen Unterschied zwischen FlowRow
und Row
. Bei Rows
basiert die Gewichtung auf allen Artikeln in Row
. Bei FlowRow
basiert die Gewichtung auf den Elementen in der Position, in der ein Element platziert wird, und nicht auf allen Elementen im Container FlowRow
.
Wenn Sie beispielsweise 4 Elemente haben, die alle auf eine Linie fallen und jedes Element eine andere Gewichtung von 1f, 2f, 1f
und 3f
hat, beträgt die Gesamtgewichtung 7f
. Der verbleibende Bereich in einer Zeile oder Spalte wird durch 7f
geteilt. Anschließend wird die Breite jedes Elements anhand von weight * (remainingSpace / totalWeight)
berechnet.
Sie können Modifier.weight
und max. Elemente mit FlowRow
oder FlowColumn
kombinieren, um ein rasterähnliches Layout zu erstellen. Dieser Ansatz ist nützlich, um responsive Layouts zu erstellen, die sich an die Größe des Geräts anpassen.
Es gibt verschiedene Beispiele dafür, was Sie mit Gewichtungen erreichen können. Ein Beispiel ist ein Raster, in dem Elemente die gleiche Größe haben, wie unten gezeigt:
So erstellen Sie ein Raster gleicher Elementgrößen:
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 ein weiteres Element hinzufügen und es zehn statt neunmal wiederholen, nimmt das letzte Element die gesamte letzte Spalte ein, da die Gesamtgewichtung für die gesamte Zeile 1f
beträgt:
Sie können Gewichtungen mit anderen Modifiers
wie Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio)
oder Modifier.fillMaxWidth(fraction)
kombinieren. Alle diese Modifikatoren sorgen dafür, dass die Größe von Elementen innerhalb von FlowRow
(oder FlowColumn
) responsiv angepasst werden kann.
Sie können auch ein abwechselndes Raster mit unterschiedlichen Elementgrößen erstellen, wobei zwei Elemente jeweils die halbe Breite einnehmen und ein Element die volle Breite der nächsten Spalte einnimmt:
Dazu können Sie 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)) } } }
Fraktionale Größen
Mit Modifier.fillMaxWidth(fraction)
können Sie die Größe des Containers angeben, den ein Element einnehmen soll. Dies unterscheidet sich von der Funktionsweise von Modifier.fillMaxWidth(fraction)
bei Anwendung auf Row
oder Column
, da Row/Column
-Elemente einen Prozentsatz der verbleibenden Breite und nicht die Breite des gesamten Containers einnehmen.
Der folgende Code führt beispielsweise zu unterschiedlichen Ergebnissen bei Verwendung von FlowRow
und 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)) }
|
|
|
fillMaxColumnWidth()
und fillMaxRowHeight()
Durch die Anwendung von Modifier.fillMaxColumnWidth()
oder Modifier.fillMaxRowHeight()
auf ein Element in einem FlowColumn
oder FlowRow
wird sichergestellt, dass Elemente in derselben Spalte oder Zeile dieselbe Breite oder Höhe wie das größte Element in der Spalte/Zeile einnehmen.
In diesem Beispiel wird FlowColumn
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 nicht 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) ) } } }
|
|
Keine Breitenänderungen festgelegt (Elemente werden umgebrochen) |
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Grundlagen zum Verfassen von Layouts
- ConstraintLayout in Compose
- Editoraktionen {:#editor-actions}