Ustawianie właściwości kontenera

Możesz zdefiniować konfigurację kontenera siatki, aby tworzyć elastyczne układy, które reagują na różne rozmiary ekranu i rodzaje treści. Na tej stronie opisujemy, jak to zrobić:

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. Poniższy 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. 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, a 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()
}

Sześć kart jest umieszczonych w siatce z 3 wierszami i 2 kolumnami.
Rysunek 1. 6 kart umieszczonych w siatce, która ma 3 wiersze i 2 kolumny.

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()
}

Funkcja przepływu zmienia kierunek umieszczania elementów.
Rysunek 2. GridFlow.Row (po lewej) i GridFlow.Column (po prawej).

Zarządzanie rozmiarami ścieżek

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 od 0.0f do 1.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 na 1.fr i 3.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.

W tym przykładzie do określenia wysokości wierszy używane są różne opcje rozmiaru ścieżki:

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")

}

Wysokości wierszy określone za pomocą 4 podstawowych opcji rozmiaru ścieżki.
Rysunek 3. Wysokości wierszy określone za pomocą 4 podstawowych opcji rozmiaru ścieżki w Grid.

Ustawianie minimalnego rozmiaru elastycznych ścieżek siatki

Gdy kontener siatki nie ma już miejsca, standardowa elastyczna ścieżka może się zmniejszyć do 0.dp. Aby temu zapobiec i zapewnić, że treść nie zostanie zniekształcona, użyj GridTrackSize.MinMax aby wymusić wyraźny 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)")
}

Wysokości wierszy określone za pomocą 4 podstawowych opcji rozmiaru ścieżki.
Rysunek 4. Pierwszy wiersz ma co najmniej 100.dp wysokości.

Ustawianie minimalnego rozmiaru ścieżki siatki w celu umieszczenia list leniwych

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 wyraźnym 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("Lazy column 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")
        }
    }
}

Wysokości wierszy określone za pomocą 4 podstawowych opcji rozmiaru ścieżki.
Rysunek 5. 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 umieszczenie 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 jak MaxContent, ale zmniejsza się i zawija treść, aby zmieścić się w kontenerze nadrzędnym.

Ten przykład umieszcza 2 teksty obok siebie. Rozmiar kolumny 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.")
}

Rozmiary wewnętrzne określone w kolumnach.
Rysunek 5. Rozmiary wewnętrzne określone w kolumnach.

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()
}

odstępy między wierszami i kolumnami;
Rysunek 6. Odstępy między wierszami i kolumnami.

Możesz też użyć wygodnej funkcji gap aby zdefiniować odstępy o tym samym rozmiarze kolumny i wiersza, oraz zdefiniować rozmiary kolumn i odstępów osobno 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()
}