FlowRow
i FlowColumn
to elementy kompozycyjne podobne do elementów Row
i Column
, ale różnią się tym, że gdy w kontenerze zabraknie miejsca, przechodzą do następnego wiersza. Spowoduje to utworzenie wielu wierszy lub kolumn. Liczbę elementów w elemencie można też kontrolować za pomocą ustawień maxItemsInEachRow
lub maxItemsInEachColumn
. Do tworzenia układów elastycznych często możesz używać elementów FlowRow
i FlowColumn
, ponieważ jeśli elementy są za duże na jeden wymiar, zawartość nie zostanie przycięta. Użycie kombinacji atrybutów maxItemsInEach*
i Modifier.weight(weight)
może pomóc w tworzeniu układów, które w razie potrzeby wypełniają lub rozszerzają szerokość wiersza lub kolumny.
Typowy przykład dotyczy elementu lub interfejsu filtrowania:
Podstawowe użycie
Aby używać FlowRow
lub FlowColumn
, utwórz taki element i umieść w nim 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") } }
Ten fragment kodu powoduje wyświetlenie interfejsu użytkownika widocznego powyżej, a elementy automatycznie przechodzą do następnego wiersza, gdy w pierwszym wierszu nie będzie już miejsca.
Funkcje układu przepływu
Układy przepływu mają opisane poniżej funkcje i właściwości, których możesz użyć do tworzenia różnych układów w aplikacji.
Układ osi głównej: układ w poziomie lub w pionie
Oś główna to oś, na której są rozmieszczone elementy (np. w FlowRow
elementy są rozmieszczone poziomo). Parametr horizontalArrangement
w elemencie FlowRow
określa sposób rozdzielania wolnego miejsca między elementy.
W poniższej tabeli znajdziesz przykłady ustawień horizontalArrangement
w elementach w przypadku elementu FlowRow
:
Ustawiono układ poziomy w: |
Wynik |
|
|
W przypadku FlowColumn
podobne opcje są dostępne w usłudze verticalArrangement
, której domyślna wartość to Arrangement.Top
.
Układ osi poprzecznej
Oś krzyżowa to oś w przeciwnym kierunku niż oś główna. Na przykład w polu FlowRow
oś pionowa jest widoczna. Aby zmienić układ całej zawartości kontenera na osi krzyżowej, użyj verticalArrangement
dla FlowRow
i horizontalArrangement
dla FlowColumn
.
W przypadku FlowRow
w tabeli poniżej znajdziesz przykłady konfigurowania różnych wartości verticalArrangement
w elementach:
Ustawiono ustawienie pionowe w: |
Wynik |
|
|
W przypadku usługi FlowColumn
podobne opcje są dostępne w usłudze horizontalArrangement
.
Domyślny układ osi krzyżowej to Arrangement.Start
.
Wyrównanie poszczególnych elementów
Niektóre elementy możesz umieścić w wierszu z różnym wyrównaniem. Różni się od verticalArrangement
i horizontalArrangement
, ponieważ wyrównuje elementy w obrębie bieżącego zamówienia. Możesz to zrobić w Modifier.align()
.
Jeśli np. elementy w polu FlowRow
mają różne wysokości, wiersz pobiera wysokość największego elementu i stosuje do nich właściwość Modifier.align(alignmentOption)
:
W kolumnie |
Wynik |
|
|
W przypadku usługi FlowColumn
dostępne są podobne opcje. Domyślnie wyrównanie to Alignment.Start
.
Maksymalna liczba elementów w wierszu lub kolumnie
Parametry maxItemsInEachRow
i maxItemsInEachColumn
określają maksymalną dozwoloną liczbę elementów na osi głównej w jednym wierszu przed zawijaniem do kolejnego. Wartość domyślna to Int.MAX_INT
, która zezwala na jak największą liczbę elementów, o ile ich rozmiary pozwalają na zmieszczenie się w wierszu.
Na przykład ustawienie maxItemsInEachRow
wymusza w pierwszym układzie tylko 3 elementy:
Nie ustawiono maksymalnej wartości |
|
Leniwe ładowanie elementów procesu
ContextualFlowRow
i ContextualFlowColumn
to specjalistyczna wersja FlowRow
i FlowColumn
, która umożliwia leniwe ładowanie zawartości wiersza lub kolumny przepływu. Dostarczają też informacji 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 oraz wtedy, gdy potrzebujesz informacji kontekstowych o elemencie.
Parametr maxLines
ogranicza liczbę wyświetlanych wierszy, a parametr overflow
określa, co powinno się wyświetlać po osiągnięciu nadmiaru elementów. Pozwala to określić 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") }
Wagi produktów
Waga zwiększa wartość elementu na podstawie jego współczynnika i dostępnej przestrzeni w linii, w której został umieszczony. Istotnie jest różnica między FlowRow
a Row
w kwestii sposobu obliczania szerokości elementu przy użyciu wagi. W przypadku Rows
waga jest określana na podstawie wszystkich elementów w elemencie Row
. W przypadku FlowRow
waga jest określana na podstawie elementów zamówienia, w których znajduje się dany element, a nie wszystkich elementów w kontenerze FlowRow
.
Jeśli np. masz 4 elementy w wierszu, z których każdy ma inną wagę 1f, 2f, 1f
i 3f
, łączna waga wyniesie 7f
. Pozostałe miejsce w wierszu lub kolumnie zostanie podzielone przez 7f
. Następnie szerokość każdego elementu zostanie obliczona za pomocą wzoru: weight * (remainingSpace / totalWeight)
.
Aby utworzyć układ przypominający siatkę, możesz użyć kombinacji elementów Modifier.weight
i maksymalnej liczby elementów z atrybutem FlowRow
lub FlowColumn
. Ta metoda przydaje się do tworzenia układów elastycznych, które dostosowują się do rozmiaru urządzenia.
Istnieje kilka różnych przykładów tego, co można osiągnąć za pomocą wag. Jednym z przykładów jest siatka, w której elementy mają równe rozmiary:
Aby utworzyć siatkę produktów o równych rozmiarach, możesz wykonać 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) } }
Pamiętaj, że jeśli dodasz kolejny element i powtórzysz go 10 razy zamiast 9, ostatni element zajmie całą ostatnią kolumnę, ponieważ łączna waga dla całego wiersza wynosi 1f
:
Wagi możesz łączyć z innymi właściwościami Modifiers
, np. Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio)
lub Modifier.fillMaxWidth(fraction)
. Wszystkie te modyfikatory działają w połączeniu, umożliwiając elastyczne określanie rozmiaru elementów w elemencie FlowRow
(lub FlowColumn
).
Możesz też utworzyć naprzemienne siatkę o różnych rozmiarach elementów, w której 2 elementy zajmują połowę szerokości, a 1 – na całą szerokość następnej kolumny:
Możesz to zrobić 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łamkowe rozmiary
Za pomocą właściwości Modifier.fillMaxWidth(fraction)
możesz określić rozmiar kontenera, w którym powinien się znajdować element. Różni się to od sposobu działania Modifier.fillMaxWidth(fraction)
po zastosowaniu do Row
lub Column
, ponieważ elementy Row/Column
zajmują procent pozostałej szerokości, a nie szerokość całego kontenera.
Na przykład ten kod daje różne wyniki w przypadku użycia funkcji FlowRow
i 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 właściwości Modifier.fillMaxColumnWidth()
lub Modifier.fillMaxRowHeight()
do elementu w elemencie FlowColumn
bądź FlowRow
gwarantuje, że elementy w tej samej kolumnie lub wierszu będą mieć taką samą szerokość lub wysokość jak największy element w kolumnie/wierszu.
Na przykład w tym przykładzie używamy słowa FlowColumn
, aby wyświetlić listę deserów na Androida. Możesz zobaczyć różnicę w szerokościach poszczególnych elementów, gdy atrybut Modifier.fillMaxColumnWidth()
jest stosowany do elementów, a gdy nie i które są zawijane.
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 |
|
Nie ustawiono zmian szerokości (elementy zawijania) |
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy JavaScript jest wyłączony
- Podstawowe informacje o układzie wiadomości
- ConstraintUkład w oknie tworzenia wiadomości
- Działania edytora {:#editor-actions}