Listy leniwe w siatce

Ikona oceny 4 gwiazdek

Funkcja kompozycyjna Grid tworzy strukturalne, dwuwymiarowe układy ekranu. Grid definiuje strukturę układu elastycznego, używając wyraźnie określonych ścieżek (wierszy i kolumn) oraz odstępów jako podstawowej architektury interfejsu.

Grid jest kontenerem strukturalnym, a nie kontenerem z leniwym ładowaniem, dlatego wymaga jawnego zdefiniowania każdego elementu, który się w nim znajduje, bez ponownego wykorzystywania elementów podczas przewijania. W rezultacie renderowanie dużych lub dynamicznych zbiorów danych bezpośrednio w komponencie 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 Lazy, takie jak LazyColumn lub LazyRow. Pamiętaj jednak, że ścieżki elastyczne (ze specyfikacjami 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 ścieżce elastycznej powoduje awarię IllegalStateException. Aby bezpiecznie umieścić listy z opóźnionym ładowaniem w elastycznym torze siatki, musisz użyć rozmiaru GridTrackSize.MinMax (np. minmax(0.dp, 1.fr)), aby pominąć etap pomiaru wewnętrznego.

Układ ekranu z nagłówkiem u góry, przewijaną listą elementów w głównym obszarze treści i stopką u dołu.
Rysunek 1. Strukturalny układ ekranu z nagłówkiem, stopką i umieszczonym 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 uporządkowanym komponencie Grid, umieść komponenty leniwe (zwykle LazyColumn lub LazyRow) w określonych komórkach siatki, zamiast tworzyć duże pętle jawne nad elementami, ponieważ Grid nie wykorzystuje ponownie elementów i ma limit 1000 ścieżek.
  • Używaj rozmiaru ścieżki MinMax w przypadku list leniwych: ponieważ LazyColumn i LazyRow nie obsługują wewnętrznych przebiegów pomiarowych (patrz SubcomposeLayout), używaj GridTrackSize.MinMax na elastycznych ścieżkach hostujących komponenty leniwe, aby bezpiecznie omijać pomiary wewnętrzne.

Składniki

  • Grid: układ kompozycyjny, który umieszcza elementy w dwuwymiarowej strukturze siatki skonfigurowanej za pomocą jawnych ścieżek wierszy i kolumn.
  • LazyColumn: przewijana w pionie lista, która tworzy i wykorzystuje ponownie tylko elementy widoczne obecnie na ekranie.
  • GridTrackSize.MinMax: właściwość określająca rozmiar ścieżki, która definiuje elastyczne granice (min i max) w celu bezpiecznego hostowania komponentów leniwych bez wywoływania awarii pomiarów w czasie działania.
  • gridItem: rozszerzenie Compose Modifier, które przypisuje podrzędny element interfejsu do konkretnej komórki lub nazwanego obszaru w elemencie Grid.

Kroki

Uporządkuj układ ekranu, definiując semantyczne identyfikatory obszarów, konfigurując ścieżki siatki z rozmiarem minmax, aby zapewnić zgodność z listą leniwą, i osadzając LazyColumn w obszarze zawartości siatki.

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

Utwórz klasę enum, która będzie reprezentować różne regiony układu ekranu, i zdefiniuj funkcję lambda GridConfigurationScope dla ścieżek układu i nazwanych obszarów. Użyj GridTrackSize.MaxContent dla wierszy nagłówka i stopki, aby dopasować je do wymiarów zawartości, i minmax(0.dp, 1.fr) dla ścieżki zawartości, która zawiera listę leniwą, 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 funkcji kompozycyjnej przekaż lazyConfig do kontenera Grid. Wewnątrz funkcji lambda content umieść komponenty statyczne (Header i Footer) i ustaw je za pomocą Modifier.gridItem() z odpowiednimi identyfikatorami obszarów.

3. Umieszczanie LazyColumn w obszarze treści

W komórce treści umieść LazyColumn, używając Modifier.gridItem(ScreenArea.Content). Ponieważ w kroku 1 ścieżka treści została skonfigurowana z użyciem minmax(0.dp, 1.fr), 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 wykorzystuje teraz interfejs API Grid do definiowania ogólnej dwuwymiarowej struktury strony, a jednocześnie umieszcza element LazyColumn w elastycznej ścieżce o rozmiarze minmax, aby efektywnie wykorzystywać elementy listy i unikać wyjątków w czasie działania.

Dodatkowe materiały