Elenchi pigri in una griglia

Icona di valutazione a quattro stelle

Il composable Grid crea layout dello schermo strutturali e bidimensionali. Grid definisce una struttura di layout adattabile utilizzando tracce (righe e colonne) e spazi vuoti definiti in modo esplicito come architettura di base della UI.

Poiché Grid è un contenitore strutturale anziché con caricamento lento, richiede di definire esplicitamente ogni elemento al suo interno senza riciclare gli elementi durante lo scorrimento. Di conseguenza, il rendering di set di dati di grandi dimensioni o dinamici direttamente all'interno di un Grid può causare colli di bottiglia delle prestazioni, poiché tutti gli elementi vengono composti contemporaneamente.

Per visualizzare grandi raccolte di dati all'interno di un layout dello schermo strutturato, incorpora componenti lazy come LazyColumn o LazyRow nelle celle Grid. Tuttavia, tieni presente che le tracce flessibili (con specifiche come 1.fr) eseguono query sulle dimensioni intrinseche degli elementi secondari. Poiché SubcomposeLayout non supporta i passaggi di misurazione intrinseci, l'inserimento di un elenco lazy all'interno di una traccia flessibile causa un arresto anomalo di IllegalStateException. Per posizionare in sicurezza gli elenchi lazy all'interno di una traccia di griglia flessibile, devi utilizzare il dimensionamento GridTrackSize.MinMax (ad esempio minmax(0.dp, 1.fr)) per bypassare il passaggio di misurazione intrinseca.

Layout dello schermo con un'intestazione in alto, un elenco scorrevole di elementi nell'area dei contenuti principali e un piè di pagina in basso.
Figura 1. Layout strutturale dello schermo con un'intestazione, un piè di pagina e un LazyColumn incorporato per i contenuti.

Best practice

  • Utilizza elenici lazy anziché loop espliciti di grandi dimensioni: per visualizzare set di dati di grandi dimensioni o dinamici all'interno di un Grid strutturato, incorpora componenti lazy (in genere LazyColumn o LazyRow) all'interno di celle di griglia specifiche anziché creare loop espliciti di grandi dimensioni sugli elementi, poiché Grid non ricicla gli elementi e ha un limite di 1000 tracce.
  • Utilizza il dimensionamento delle tracce MinMax per gli elenchi lazy: poiché LazyColumn e LazyRow non supportano i passaggi di misurazione intrinseca (consulta SubcomposeLayout), utilizza GridTrackSize.MinMax sulle tracce flessibili che ospitano componenti lazy per bypassare le misurazioni intrinseche in sicurezza.

Ingredienti

  • Grid: layout componibile che posiziona gli elementi in una struttura a griglia bidimensionale configurata utilizzando tracce di righe e colonne esplicite.
  • LazyColumn: elenco a scorrimento verticale che compone e ricicla solo gli elementi attualmente visibili sullo schermo.
  • GridTrackSize.MinMax: proprietà di dimensionamento della traccia che definisce limiti flessibili (min e max) per ospitare in sicurezza i componenti lazy senza attivare arresti anomali della misurazione di runtime.
  • gridItem: estensione di Compose Modifier che assegna un elemento UI secondario a una cella specifica o a un'area denominata all'interno di un Grid.

Passaggi

Struttura il layout dello schermo definendo identificatori di aree semantiche, configurando le tracce della griglia con il dimensionamento minmax per la compatibilità con l'elenco lazy e incorporando LazyColumn nell'area dei contenuti della griglia.

1. Configura le tracce della griglia e le aree denominate

Crea una classe enum per rappresentare le diverse regioni del layout dello schermo e definisci una funzione lambda GridConfigurationScope per le tracce del layout e le aree denominate. Utilizza GridTrackSize.MaxContent per le righe di intestazione e piè di pagina in modo che si adattino alle dimensioni dei contenuti e utilizza minmax(0.dp, 1.fr) per la traccia dei contenuti che ospita l'elenco lazy per allocare spazio flessibile senza eseguire query su misurazioni intrinseche non supportate:

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. Posiziona i componenti statici nella griglia

Nel composable, passa lazyConfig al container Grid. All'interno della funzione lambda content, inserisci i componenti statici (Header e Footer) e posizionali utilizzando Modifier.gridItem() con i rispettivi identificatori di area.

3. Incorpora LazyColumn nell'area dei contenuti

Nella cella dei contenuti, incorpora LazyColumn utilizzando Modifier.gridItem(ScreenArea.Content). Poiché il canale dei contenuti è stato configurato con minmax(0.dp, 1.fr) nel passaggio 1, LazyColumn può misurare e riciclare gli elementi in sicurezza durante lo scorrimento senza eseguire query su dimensioni intrinseche non supportate:

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

Risultati

Il layout dello schermo ora utilizza l'API Grid per definire la struttura complessiva della pagina bidimensionale, incorporando un LazyColumn in una traccia flessibile con dimensioni minmax per riciclare gli elementi dell'elenco in modo efficiente ed evitare eccezioni di runtime.

Risorse aggiuntive