FlowRow
i FlowColumn
to komponenty podobne do Row
i Column
, ale różniące się tym, że elementy przepływają na następny wiersz, gdy w kontenerze zabraknie miejsca. W ten sposób utworzysz kilka wierszy lub kolumn. Liczba elementów w pozycji może być też kontrolowana przez ustawienie maxItemsInEachRow
lub maxItemsInEachColumn
. Do tworzenia układów elastycznych często możesz użyć elementów FlowRow
i FlowColumn
– treść nie zostanie obcięta, jeśli elementy są zbyt duże, by zmieścić się w jednym wymiarze. Połączenie maxItemsInEach*
z elementem Modifier.weight(weight)
może też ułatwić tworzenie układów, które w razie potrzeby wypełniają lub poszerzają szerokość wiersza lub kolumny.
Typowy przykład interfejsu użytkownika dla elementu lub filtrowania:
Podstawowe użycie
Aby użyć funkcji FlowRow
lub FlowColumn
, utwórz te elementy kompozycyjne i umieść w nich elementy zgodnie ze standardowym procesem:
@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") } }
Po wprowadzeniu tego fragmentu interfejs wygląda jak powyżej, a elementy są automatycznie przenoszone do następnego wiersza, gdy w pierwszym wierszu nie ma więcej miejsca.
Funkcje układu przepływu
Układy przepływu mają te funkcje i właściwości, których możesz używać do tworzenia różnych układów w aplikacji.
Ułożenie głównej osi: poziome lub pionowe
Główna oś to oś, na której są rozmieszczone elementy (np. w FlowRow
elementy są rozmieszczone poziomo). Parametr horizontalArrangement
w pliku FlowRow
określa sposób rozmieszczania wolnego miejsca między elementami.
W tej tabeli znajdziesz przykłady ustawienia horizontalArrangement
w elementach FlowRow
:
Ustawiono rozmieszczenie poziome: |
Wynik |
|
|
W przypadku usługi FlowColumn
podobne opcje są dostępne w usłudze verticalArrangement
. Wartość domyślna to Arrangement.Top
.
Ustawienie osi poprzecznej
Oś poprzeczna jest osią w przeciwnym kierunku niż oś główna. Na przykład w funkcji FlowRow
jest to oś pionowa. Aby zmienić sposób rozmieszczania elementów na osi poprzecznej, użyj wartości verticalArrangement
dla FlowRow
i horizontalArrangement
dla FlowColumn
.
W tabeli poniżej znajdziesz przykłady ustawienia różnych wartości verticalArrangement
w elemencie FlowRow
:
Układ pionowy ustawiony na |
Wynik |
|
|
W przypadku FlowColumn
dostępne są podobne opcje w horizontalArrangement
.
Domyślne ustawienie osi poprzecznej to Arrangement.Start
.
Wyrównanie poszczególnych elementów
Możesz ustawić poszczególne elementy w wierszu z różnym wyrównaniem. Różni się od verticalArrangement
i horizontalArrangement
, ponieważ wyrównuje elementy w bieżącym wierszu. Możesz to zrobić za pomocą Modifier.align()
.
Jeśli na przykład elementy w elementach zbiorczych FlowRow
mają różną wysokość, wiersz przyjmuje wysokość największego elementu i stosuje do elementów zbiorczych wartość Modifier.align(alignmentOption)
:
Wyrównanie w pionie ustawiono |
Wynik |
|
|
W przypadku FlowColumn
dostępne są podobne opcje. Domyślne wyrównanie to Alignment.Start
.
Maksymalna liczba elementów w wierszu lub kolumnie
Parametry maxItemsInEachRow
i maxItemsInEachColumn
określają maksymalną liczbę elementów na osi głównej, które można umieścić w jednym wierszu przed zawijaniem do następnego. Wartość domyślna to Int.MAX_INT
, która zezwala na użycie jak największej liczby elementów, o ile tylko ich rozmiar mieści się w wierszu.
Na przykład ustawienie maxItemsInEachRow
spowoduje, że początkowy układ będzie zawierać tylko 3 elementy:
Brak ustawionego maksimum |
|
Leniwe ładowanie elementów procesu
ContextualFlowRow
i ContextualFlowColumn
to wyspecjalizowane wersje elementów FlowRow
i FlowColumn
, które umożliwiają opóźnione wczytywanie zawartości wiersza lub kolumny przepływu. Zawierają też informacje o pozycji elementów (indeksie, numerze wiersza i dostępnym rozmiarze), na przykład o tym, czy element znajduje się w pierwszym wierszu. Jest to przydatne w przypadku dużych zbiorów danych i jeśli potrzebujesz informacji kontekstowych na temat danego elementu.
Parametr maxLines
ogranicza liczbę wyświetlanych wierszy, a parametr overflow
określa, co ma się wyświetlać, gdy liczba elementów przekroczy limit. Dzięki temu możesz podać niestandardową wartość expandIndicator
lub collapseIndicator
.
Aby na przykład wyświetlić przycisk „+ (liczba pozostałych elementów)” lub „Pokaż mniej”:
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") }
Waga produktu
Waga zwiększa wagę elementu na podstawie jego współczynnika i dostępnej przestrzeni na linii, na której został umieszczony. Należy pamiętać, że FlowRow
i Row
różnią się sposobem korzystania z wag do obliczania szerokości elementu. W przypadku Rows
waga jest obliczana na podstawie wszystkich elementów w: Row
. W przypadku FlowRow
waga jest określana na podstawie elementów zamówienia w pozycji, w której znajduje się element, a nie wszystkich elementów w kontenerze FlowRow
.
Jeśli na przykład masz 4 elementy, które mieszczą się w jednej linii, a każdy z nich ma inną wagę: 1f, 2f, 1f
i 3f
, łączna waga wynosi 7f
. Pozostała przestrzeń w wierszu lub kolumnie zostanie podzielona przez 7f
. Następnie szerokość każdego elementu zostanie obliczona za pomocą: weight * (remainingSpace / totalWeight)
.
Aby utworzyć układ podobny do siatki, możesz użyć kombinacji wartości Modifier.weight
i maksymalnej liczby elementów z parametrem FlowRow
lub FlowColumn
. To podejście jest przydatne do tworzenia responsywnych układów, które dostosowują się do rozmiaru urządzenia.
Poniżej znajdziesz kilka przykładów tego, czego możesz dokonać, używając wag. Przykładem jest siatka, w której elementy mają jednakowy rozmiar, jak pokazano poniżej:
Aby utworzyć siatkę o równych rozmiarach elementów, wykonaj te czynności:
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) } }
Jeśli dodasz kolejny element i powtórzysz go 10 razy zamiast 9, ostatni element zajmie całą ostatnią kolumnę, ponieważ łączna waga całego wiersza wynosi 1f
:
Możesz łączyć wagi z innymi Modifiers
, takimi jak Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio)
lub Modifier.fillMaxWidth(fraction)
. Wszystkie te modyfikatory działają razem, aby umożliwić dostosowanie rozmiaru elementów w elementach FlowRow
(lub FlowColumn
).
Możesz też utworzyć naprzemienne siatkę z elementami o różnych rozmiarach, gdzie 2 elementy mają połowę szerokości, a jeden z nich zajmuje pełną szerokość następnej kolumny:
Można to osiągnąć za pomocą tego kodu:
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)) } } }
Ułamkowy rozmiar
Za pomocą atrybutu Modifier.fillMaxWidth(fraction)
możesz określić rozmiar kontenera, który produkt powinien zajmować. Różni się to od działania funkcji Modifier.fillMaxWidth(fraction)
po zastosowaniu do obiektu Row
lub Column
– elementy Row/Column
zajmują procent pozostałej szerokości, a nie szerokości całego kontenera.
Na przykład ten kod daje różne wyniki w zależności od tego, czy używasz funkcji FlowRow
czy 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()
i fillMaxRowHeight()
Zastosowanie Modifier.fillMaxColumnWidth()
lub
Modifier.fillMaxRowHeight()
do elementu w FlowColumn
lub FlowRow
zapewnia, że elementy w tej samej kolumnie lub wierszu mają taką samą szerokość lub wysokość jak największy element w kolumnie/wierszu.
Na przykład w tym przykładzie użyto FlowColumn
, aby wyświetlić listę deserów na Androida. Możesz zobaczyć różnicę w szerokości poszczególnych elementów, gdy zastosujesz do nich Modifier.fillMaxColumnWidth()
, a także gdy jej nie zastosujesz i elementy się zawiną.
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) ) } } }
Do każdego elementu zastosowano |
|
Brak ustawień zmiany szerokości (owijanie elementów) |
Polecane dla Ciebie
- Uwaga: tekst linku wyświetla się, gdy JavaScript jest wyłączony
- Podstawy tworzenia układu
- ConstraintLayout w Compose
- Czynności edytującego {:#editor-actions}