Listy leniwe w siatce

Ikona oceny czterech gwiazdek

Komponent Grid tworzy strukturalne, dwuwymiarowe układy ekranu. Grid definiuje strukturę układu elastycznego za pomocą jawnie zdefiniowanych ścieżek (wierszy i kolumn) oraz odstępów jako podstawowej architektury interfejsu.

Ponieważ element Grid jest kontenerem strukturalnym, a nie kontenerem leniwego ładowania, wymaga on wyraźnego zdefiniowania każdego umieszczonego w nim elementu bez ponownego wykorzystywania elementów podczas przewijania. W rezultacie renderowanie dużych lub dynamicznych zbiorów danych bezpośrednio w Grid może powodować wąskie gardła wydajności, ponieważ wszystkie elementy są tworzone jednocześnie.

Aby wyświetlać duże zbiory danych w uporządkowanym układzie ekranu, umieść w komórkach Grid komponenty ładowane z opóźnieniem, takie jak LazyColumn lub LazyRow. Pamiętaj jednak, że ścieżki elastyczne (z określeniami takimi jak 1.fr) wysyłają zapytania o rozmiary wewnętrzne elementów podrzędnych. Ponieważ SubcomposeLayout nie obsługuje wewnętrznych pomiarów, umieszczenie leniwej listy w elastycznej ścieżce powoduje awarię IllegalStateException. Aby bezpiecznie umieścić leniwe listy w elastycznej siatce, musisz użyć rozmiaru GridTrackSize.MinMax (np. minmax(0.dp, 1.fr)), aby pominąć wewnętrzny etap pomiaru.

Układ ekranu z nagłówkiem u góry, przewijaną listą elementów w głównej części treści i stopką u dołu.
Rysunek 1. Układ ekranu strukturalnego z nagłówkiem, stopką i osadzonym elementem LazyColumn na treść.

Sprawdzone metody

  • Używaj list leniwych zamiast dużych pętli jawnych: aby wyświetlać duże lub dynamiczne zbiory danych w ustrukturyzowanym elemencie Grid, umieszczaj w określonych komórkach siatki komponenty leniwe (zwykle LazyColumn lub LazyRow) zamiast tworzyć duże pętle jawne dla elementów, ponieważ Grid nie przetwarza ponownie elementów i ma limit 1000 ścieżek.
  • Użyj MinMax track sizing dla list leniwych: ponieważ LazyColumn i LazyRow nie obsługują wewnętrznych pomiarów (patrz SubcomposeLayout), użyj GridTrackSize.MinMax na elastycznych ścieżkach, które zawierają leniwe komponenty, aby bezpiecznie pominąć wewnętrzne pomiary.

Składniki

  • Grid: układ kompozycyjny, który umieszcza elementy w dwuwymiarowej siatce skonfigurowanej za pomocą jawnych ścieżek wierszy i kolumn.
  • LazyColumn: lista przewijana w pionie, która tworzy i ponownie wykorzystuje tylko elementy widoczne obecnie na ekranie.
  • GridTrackSize.MinMax: właściwość śledzenia rozmiaru, która określa elastyczne granice (minmax), aby bezpiecznie hostować komponenty ładowane z opóźnieniem bez powodowania awarii pomiarów w czasie działania.
  • gridItem: utwórz rozszerzenie Modifier, które przypisuje element interfejsu podrzędnego do określonej komórki lub nazwanego obszaru w ramach elementu Grid.

Kroki

Zdefiniuj identyfikatory obszarów semantycznych, skonfiguruj ścieżki siatki z rozmiarem minmax, aby zapewnić zgodność z listą ładowaną z opóźnieniem, i osadź element LazyColumn w obszarze treści siatki, aby uporządkować układ ekranu.

1. Konfigurowanie ścieżek siatki i nazwanych obszarów

Utwórz klasę enum, aby reprezentować różne regiony układu ekranu, i zdefiniuj lambdę GridConfigurationScope dla ścieżek układu i obszarów nazwanych. Użyj GridTrackSize.MaxContent w przypadku wierszy nagłówka i stopki, aby dopasować je do wymiarów treści, a w przypadku ścieżki treści, która zawiera listę ładowaną z opóźnieniem, użyj minmax(0.dp, 1.fr), aby przydzielić elastyczną przestrzeń bez wysyłania zapytań o nieobsługiwane pomiary wewnętrzne:

enum class ScreenArea {
    Header,
    Content,
    Footer
}


val lazyConfig: GridConfigurationScope.() -> Unit = {
    column(minmax(0.dp, 1.fr))
    row(GridTrackSize.MaxContent)
    row(minmax(0.dp, 1.fr))
    row(GridTrackSize.MaxContent)

    area(ScreenArea.Header, row = 1, column = 1)
    area(ScreenArea.Content, row = 2, column = 1)
    area(ScreenArea.Footer, row = 3, column = 1)
    gap(8.dp)
}

2. Umieszczanie komponentów statycznych w siatce

W kompozycji przekaż lazyConfig do kontenera Grid. Wewnątrz funkcji lambda content umieść statyczne komponenty (Header i Footer) i ustaw je za pomocą Modifier.gridItem() z odpowiednimi identyfikatorami obszarów.

3. Umieść LazyColumn w obszarze treści

W komórce treści umieść LazyColumn za pomocą Modifier.gridItem(ScreenArea.Content). Ponieważ ścieżka treści została skonfigurowana z parametrem minmax(0.dp, 1.fr) w kroku 1,LazyColumn może bezpiecznie mierzyć i ponownie wykorzystywać elementy podczas przewijania bez wysyłania zapytań o nieobsługiwane wymiary wewnętrzne:

@Composable
fun GridWithLazyColumn(
    modifier: Modifier = Modifier,
    items: List<String> = emptyList(),
) {
    Grid(
        modifier = modifier.fillMaxSize(),
        config = lazyConfig
    ) {
        Text("Header", Modifier.gridItem(ScreenArea.Header).padding(16.dp))
        Text("Footer", Modifier.gridItem(ScreenArea.Footer).padding(16.dp))

        // LazyColumn placed in the content area for large datasets
        LazyColumn(
            modifier = Modifier
                .gridItem(ScreenArea.Content)
                .fillMaxSize(),
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            items(items) { item ->
                Text(item, Modifier.padding(16.dp))
            }
        }
    }
}

Wyniki

Układ ekranu korzysta teraz z interfejsu Grid API do definiowania ogólnej dwuwymiarowej struktury strony, a jednocześnie osadza LazyColumn w elastycznej ścieżce o rozmiarze minmax, aby wydajnie wykorzystywać elementy listy i unikać wyjątków w czasie działania.

Dodatkowe materiały