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 wierszu może być też kontrolowana przez ustawienie maxItemsInEachRow
lub maxItemsInEachColumn
. Do tworzenia układów responsywnych często używa się elementów FlowRow
i FlowColumn
– treści nie będą obcinane, jeśli elementy są zbyt duże dla jednego wymiaru. Użycie kombinacji elementów maxItemsInEach*
i Modifier.weight(weight)
może pomóc w tworzeniu układów, które w razie potrzeby wypełniają/rozwijają szerokość wiersza lub kolumny.
Typowy przykład interfejsu użytkownika dla elementu lub filtrowania:
Podstawowe użycie
Aby używać komponentów FlowRow
lub FlowColumn
, utwórz te komponenty i umieścić w nich elementy, które powinny być zgodne ze standardowym przepływem:
@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 pokazanego powyżej. Gdy w pierwszym rzędzie zabraknie miejsca, elementy są automatycznie przenoszone do następnego rzędu.
Funkcje układu przepływowego
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 tabeli poniżej znajdziesz przykłady ustawień horizontalArrangement
dla elementów FlowRow
:
Ustawienie wyrównania poziomego: |
Wynik |
|
|
W przypadku FlowColumn
dostępne są podobne opcje z verticalArrangement
, a domyślna wartość 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 ustawień różnych wartości verticalArrangement
dla elementów 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. Ta funkcja różni się od funkcji verticalArrangement
i horizontalArrangement
, ponieważ wyrównuje elementy w ramach bieżącego wiersza. 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 ustawione na |
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
lub maxItemsInEachColumn
określają maksymalną liczbę elementów na osi głównej, która może się zmieścić na jednym wierszu przed przejściem na następny. Wartość domyślna to Int.MAX_INT
, która pozwala na wyświetlenie jak największej liczby elementów, o ile ich rozmiary umożliwiają ich umieszczenie w linii.
Na przykład ustawienie maxItemsInEachRow
spowoduje, że początkowy układ będzie zawierać tylko 3 elementy:
Brak ustawionej wartości maksymalnej |
|
Leniwe ładowanie elementów
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ą one również informacje o pozycji elementów (indeks, numer wiersza i dostępny rozmiar), np. 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ć niestandardowy parametr 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 elementów Modifier.weight
i max z elementami FlowRow
lub FlowColumn
. To podejście jest przydatne do tworzenia responsywnych układów, które dostosowują się do rozmiaru urządzenia.
Oto kilka przykładów tego, co możesz osiągnąć dzięki zastosowaniu 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ć przemienną siatkę z różnymi rozmiarami elementów, w której 2 elementy zajmują po połowie szerokości, a jeden element zajmuje całą 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óżnica w sposobie działania elementu Modifier.fillMaxWidth(fraction)
w przypadku elementów Row
lub Column
polega na tym, że elementy Row/Column
zajmują procentową część pozostałej szerokości, a nie całej szerokości 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) ) } } }
Wartość |
|
Brak ustawień zmiany szerokości (owijanie elementów) |
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy obsługa JavaScript jest wyłączona
- Podstawy tworzenia układu
- ConstraintLayout w Compose
- Czynności edytującego {:#editor-actions}