Możesz zdefiniować konfigurację kontenera siatki, aby tworzyć elastyczne układy, które reagują na różne rozmiary ekranu i rodzaje treści. Z tej strony dowiesz się, jak:
- zdefiniować siatkę: skonfigurować podstawową strukturę wierszy i kolumn;
- umieścić elementy w siatce: dowiedzieć się, jak elementy są umieszczane w komórkach siatki i jak zmienić kierunek przepływu;
- zarządzać rozmiarem ścieżki: używać stałych, procentowych, elastycznych i wewnętrznych rozmiarów, aby ustawić rozmiary ścieżek;
- ustawiać odstępy: zarządzać „marginesami” między wierszami i kolumnami.
Definiowanie siatki
Siatka składa się z kolumn i wierszy.
Komponent Grid ma parametr config
który akceptuje lambdę do definiowania kolumn i wierszy
w GridConfigurationScope.
Ten przykład definiuje siatkę, która ma 3 wiersze i 2 kolumny,
a każda z nich ma stały rozmiar określony w Dp:
Grid( config = { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } } ) { }
Umieszczanie elementów w siatce
Grid pobiera elementy interfejsu w lambdzie content i umieszcza je w komórkach siatki.
Siatka rozmieszcza elementy niezależnie od tego, czy wiersze i kolumny zostały zdefiniowane w sposób jawny.
Domyślnie Grid próbuje umieścić element interfejsu w dostępnej komórce siatki w wierszu. Jeśli nie jest to możliwe, umieszcza go w dostępnej komórce siatki w następnym wierszu.
Jeśli nie ma pustych komórek, Grid tworzy nowy wiersz.
W tym przykładzie siatka ma 6 komórek i w każdej z nich umieszczona jest karta (rysunek 1).
Każda komórka siatki ma wymiary 160dp x 90dp, co daje łączny rozmiar siatki 320dp x 270dp.
Grid( config = { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } } ) { Card1() Card2() Card3() Card4() Card5() Card6() }
Aby zmienić to domyślne zachowanie na wypełnianie według kolumny,
ustaw właściwość flow na GridFlow.Column.
Grid( config = { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } gap(8.dp) flow = GridFlow.Column // Grid tries to place items to fill the column }, ) { Card1() Card2() Card3() Card4() Card5() Card6() }
GridFlow.Row (po lewej) i GridFlow.Column (po prawej).
Zarządzanie rozmiarem ścieżki
Wiersze i kolumny są łącznie nazywane ścieżką siatki. Rozmiar ścieżki siatki możesz określić na jeden z tych sposobów:
- Stały (
Dp): przydziela określony rozmiar (np.column(180.dp)). - Procentowy (
Float): przydziela procent całkowitej dostępnej przestrzeni od0.0fdo1.0f(np.row(0.5f)dla 50%). - Elastyczny (
Fr): proporcjonalnie rozdziela pozostałą przestrzeń po obliczeniu ścieżek stałych i procentowych. Jeśli na przykład 2 wiersze są ustawione na1.fri3.fr, ten drugi otrzyma 75% pozostałej wysokości. - Wewnętrzny: określa rozmiar ścieżki na podstawie jej zawartości. Więcej informacji znajdziesz w artykule Określanie rozmiaru ścieżki siatki w sposób wewnętrzny.
Ten przykład używa różnych opcji rozmiaru ścieżki do zdefiniowania wysokości wierszy:
Grid( config = { column(1f) row(100.dp) row(0.2f) row(1.fr) row(GridTrackSize.Auto) }, modifier = Modifier.height(480.dp) ) { PastelRedCard("Fixed(100.dp)") PastelGreenCard("Percentage(0.2f)") PastelBlueCard("Flex(1.fr)") PastelYellowCard("Auto") }
Grid.
Ustawianie minimalnego rozmiaru elastycznych ścieżek siatki
Gdy kontener siatki nie ma już wolnego miejsca, standardowa elastyczna ścieżka może się zmniejszyć do 0.dp.
Aby temu zapobiec i mieć pewność, że treść nie zostanie zniekształcona,
użyj GridTrackSize.MinMax
aby wymusić jawny minimalny rozmiar, zachowując elastyczność ścieżki.
Ten przykład przydziela co najmniej 100.dp do pierwszego wiersza:
Grid( config = { column(1f) // The first row has a minimum height of 100.dp and can expand to // the half of the remaining space. row(GridTrackSize.MinMax(100.dp, 1.fr)) // The second row takes the half of the remaining space. row(1.fr) // The third row has a fixed height of 200.dp. row(200.dp) }, modifier = Modifier.size(360.dp) // Total grid height is 360.dp ) { PastelRedCard("MinMax(100.dp, 1.fr)") PastelGreenCard("Flex(1.fr)") PastelBlueCard("Fixed(200.dp)") }
100.dp.
Ustawianie minimalnego rozmiaru ścieżki siatki, aby umieszczać listy leniwe
Standardowe elastyczne ścieżki automatycznie wysyłają zapytania o wewnętrzne rozmiary swoich elementów podrzędnych, aby ustalić rozmiar podstawowy.
Jetpack Compose zabrania jednak wysyłania zapytań o wewnętrzne rozmiary
SubcomposeLayout, które obsługuje komponenty,
takie jak LazyColumn i LazyRow.
Umieszczenie listy leniwej w standardowej elastycznej ścieżce powoduje
awarię IllegalStateException.
Aby bezpiecznie umieścić listy leniwe w elastycznej ścieżce siatki, użyj MinMax z jawnym minimalnym rozmiarem (np. 0.dp), aby pominąć wewnętrzny etap pomiaru.
Grid( config = { column(1f) // The first row's height is determined by the height of the Text composable. row(GridTrackSize.Auto) // The second row occupies the remaining space, allowing the LazyColumn to scroll. row(GridTrackSize.MinMax(0.dp, 1.fr)) gap(8.dp) }, modifier = Modifier.size(width = 170.dp, height = 240.dp) ) { Text("LazyColumn in a Grid") // The LazyColumn is placed in the second row, filling the remaining space. LazyColumn(verticalArrangement = Arrangement.spacedBy(4.dp)) { items(100) { number -> PastelGreenCard("Card $number") } } }
LazyColumn w komórce siatki.
Określanie rozmiaru ścieżki siatki w sposób wewnętrzny
Możesz użyć rozmiaru wewnętrznego dla Grid
gdy chcesz, aby układ dostosowywał się do treści,
a nie wymuszał jej umieszczenia w kontenerze o stałym rozmiarze.
Rozmiar ścieżki siatki jest określany na podstawie tych wartości:
GridTrackSize.MaxContent: użyj maksymalnego wewnętrznego rozmiaru treści (np. szerokość jest określana przez pełną długość tekstu w bloku tekstowym bez zawijania).GridTrackSize.MinContent: użyj minimalnego wewnętrznego rozmiaru treści (np. szerokość jest określana przez najdłuższe pojedyncze słowo w bloku tekstowym).GridTrackSize.Auto: użyj elastycznego rozmiaru ścieżki, który dostosowuje się do dostępnej przestrzeni. Domyślnie działa jakMaxContent, ale zmniejsza się i zawija treść, aby zmieścić się w kontenerze nadrzędnym.
Ten przykład umieszcza 2 teksty obok siebie. Rozmiar kolumny dla pierwszego tekstu jest określany przez minimalną szerokość wymaganą do wyświetlenia tekstu, a szerokość drugiej kolumny zależy od maksymalnej szerokości tekstu.
Grid( config = { column(GridTrackSize.MinContent) column(GridTrackSize.MaxContent) row(1.0f) }, modifier = Modifier.width(480.dp) ) { Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras imperdiet.") Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras imperdiet.") }
Ustawianie odstępów między wierszami i kolumnami
Po określeniu rozmiaru ścieżek siatki,
możesz zmodyfikować odstęp siatki, aby dopracować odstępy między ścieżkami.
Odstęp między kolumnami możesz określić za pomocą funkcji columnGap,
a odstęp między wierszami za pomocą funkcji rowGap. W tym przykładzie między każdym wierszem jest odstęp 16dp, a między każdą kolumną – 8dp (rysunek 5).
Grid( config = { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } rowGap(16.dp) columnGap(8.dp) } ) { Card1() Card2() Card3() Card4() Card5() Card6() }
Możesz też użyć funkcji pomocniczej gap
aby zdefiniować odstępy o tym samym rozmiarze kolumny i wiersza,
oraz aby zdefiniować rozmiary kolumn i odstępów oddzielnie za pomocą jednej funkcji.
Ten kod dodaje do siatki odstępy 8dp:
Grid( config = { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } gap(8.dp) // Equivalent to columnGap(8.dp) and rowGap(8.dp) } ) { Card1() Card2() Card3() Card4() Card5() Card6() }
Definiowanie obszarów siatki za pomocą obszarów nazwanych
Obszary nazwane umożliwiają przypisywanie nazw do grup komórek siatki, które są nazywane obszarami siatki. Podczas umieszczania elementów interfejsu w siatce możesz używać tych nazw zamiast indeksów współrzędnych.
Używanie obszarów nazwanych ma 2 główne zalety w zakresie czytelności kodu:
- Podczas definiowania układu siatki cel i umiejscowienie oczekiwanej treści są jasne.
- Podczas dodawania treści jej cel jest jasny.
Aby przejrzyście organizować złożone układy, możesz oddzielić fizyczną strukturę siatki od umieszczania elementów podrzędnych, definiując semantyczne obszary siatki.
W lambdzie config użyj funkcji area w
GridConfigurationScope, aby zarejestrować obszary nazwane w siatce.
Następnie możesz przypisać do tych obszarów komponenty podrzędne
za pomocą gridItem modyfikatora
z odpowiednim identyfikatorem obszaru. Funkcja area mapuje identyfikator semantyczny (np. wartość klasy enum lub klucz ciągu znaków) na zestaw fizycznych współrzędnych siatki. Linie i indeksy siatki są liczone od 1 (czyli pierwszy wiersz to 1, a pierwsza kolumna to 1).
Możesz na przykład zdefiniować siatkę, która ma 4 identyfikatory obszarów:
/** * An enum representing the IDs for named areas within the grid. */ enum class GridAreaNames { Area1, Area2, Area3, Area4 }
Podaj nazwę obszaru za pomocą parametru areaId wraz ze współrzędnymi komórek i rozpiętościami obszaru.
Modyfikator gridItem używa areaId jako klucza do przypisania każdego elementu podrzędnego do jego wyznaczonego obszaru siatki, jak pokazano w tym przykładzie:
Grid( config = { // Define a single column that takes all available width. repeat(2) { column(0.5f) } // Define four rows, each taking 25% of the total height. repeat(4) { row(0.25f) } // Define named grid areas by associating an areaId with specific row and column indices. // Row and column indices are 1-based. area(areaId = GridAreaNames.Area1, row = 1, column = 1, columnSpan = 2) area(areaId = GridAreaNames.Area2, row = 2, column = 1, rowSpan = 3) area(areaId = GridAreaNames.Area3, rows = 2..3, columns = 2..2) area(areaId = GridAreaNames.Area4, row = 4, column = 2) gap(4.dp) }, modifier = Modifier.size(360.dp) ) { PastelRedCard( "Area 1", // Use Modifier.gridItem(areaId) to place this composable into the // grid area defined with the matching ID in the config block. modifier = Modifier.gridItem(areaId = GridAreaNames.Area1) ) PastelGreenCard( "Area 2", modifier = Modifier.gridItem(areaId = GridAreaNames.Area2) ) PastelBlueCard( "Area 3", modifier = Modifier.gridItem(areaId = GridAreaNames.Area3) ) PastelYellowCard( "Area 4", modifier = Modifier.gridItem(areaId = GridAreaNames.Area4) ) }
Używając obszarów nazwanych, możesz reorganizować lub dostosowywać fizyczną siatkę układu (np. zmieniać wiersze, kolumny lub rozmiary ścieżek) w lambdzie config bez konieczności modyfikowania kolejności ani parametrów komponentów podrzędnych.