Listes différées dans une grille

Icône de note à quatre étoiles

Le composable Grid crée des mises en page d'écran structurelles et bidimensionnelles. Grid définit une structure de mise en page responsive à l'aide de pistes (lignes et colonnes) et d'espaces explicitement définis comme architecture de base de votre UI.

Étant donné que Grid est un conteneur structurel plutôt qu'un conteneur à chargement différé, vous devez définir explicitement chaque élément qui y est placé sans recycler les éléments lors du défilement. Par conséquent, l'affichage d'ensembles de données volumineux ou dynamiques directement dans un Grid peut entraîner des goulots d'étranglement des performances, car tous les éléments sont composés simultanément.

Pour afficher de grandes collections de données dans une mise en page structurée, intégrez des composants à chargement différé tels que LazyColumn ou LazyRow dans vos cellules Grid. Toutefois, notez que les pistes flexibles (avec des spécifications telles que 1.fr) interrogent les tailles intrinsèques des éléments enfants. Étant donné que SubcomposeLayout n'est pas compatible avec les passes de mesure intrinsèques, le placement d'une liste différée dans une piste flexible entraîne un plantage IllegalStateException. Pour placer des listes à chargement différé de manière sécurisée dans une piste de grille flexible, vous devez utiliser une taille GridTrackSize.MinMax (comme minmax(0.dp, 1.fr)) pour contourner la passe de mesure intrinsèque.

Mise en page avec un en-tête en haut, une liste d'éléments à faire défiler dans la zone de contenu principal et un pied de page en bas.
Figure 1. Mise en page structurelle avec un en-tête, un pied de page et un LazyColumn intégré pour le contenu.

Bonnes pratiques

  • Utilisez des listes paresseuses au lieu de grandes boucles explicites : pour afficher des ensembles de données volumineux ou dynamiques dans un Grid structuré, intégrez des composants paresseux (généralement LazyColumn ou LazyRow) dans des cellules de grille spécifiques au lieu de créer de grandes boucles explicites sur les éléments, car Grid ne recycle pas les éléments et est limité à 1 000 pistes.
  • Utiliser le dimensionnement des pistes MinMax pour les listes à chargement différé : comme LazyColumn et LazyRow ne prennent pas en charge les passes de mesure intrinsèques (voir SubcomposeLayout), utilisez GridTrackSize.MinMax sur les pistes flexibles hébergeant des composants à chargement différé pour contourner les mesures intrinsèques de manière sécurisée.

Ingrédients

  • Grid : mise en page composable qui place les éléments dans une structure de grille bidimensionnelle configurée à l'aide de pistes de lignes et de colonnes explicites.
  • LazyColumn : liste à défilement vertical qui compose et recycle uniquement les éléments actuellement visibles à l'écran.
  • GridTrackSize.MinMax : propriété de dimensionnement de piste qui définit des limites flexibles (min et max) pour héberger en toute sécurité les composants à chargement différé sans déclencher de plantages de mesure d'exécution.
  • gridItem : extension Compose Modifier qui attribue un élément d'interface utilisateur enfant à une cellule ou une zone nommée spécifique à l'intérieur d'un Grid.

Étapes

Structurez la mise en page de votre écran en définissant des identifiants de zone sémantiques, en configurant des pistes de grille avec un dimensionnement minmax pour la compatibilité avec les listes à chargement différé et en intégrant LazyColumn dans la zone de contenu de la grille.

1. Configurer les pistes de grille et les zones nommées

Créez une classe enum pour représenter les différentes régions de la mise en page de votre écran, et définissez un lambda GridConfigurationScope pour vos pistes de mise en page et vos zones nommées. Utilisez GridTrackSize.MaxContent pour que les lignes d'en-tête et de pied de page s'adaptent aux dimensions de leur contenu, et utilisez minmax(0.dp, 1.fr) pour que la piste de contenu hébergeant la liste différée alloue un espace flexible sans interroger les mesures intrinsèques non compatibles :

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. Placer des composants statiques dans la grille

Dans votre composable, transmettez lazyConfig au conteneur Grid. Dans le lambda content, placez les composants statiques (Header et Footer) et positionnez-les à l'aide de Modifier.gridItem() avec leurs identifiants de zone respectifs.

3. Intégrer LazyColumn dans la zone de contenu

Dans la cellule de contenu, intégrez LazyColumn à l'aide de Modifier.gridItem(ScreenArea.Content). Étant donné que le suivi du contenu a été configuré avec minmax(0.dp, 1.fr) à l'étape 1, LazyColumn peut mesurer et recycler les éléments au défilement en toute sécurité, sans interroger les dimensions intrinsèques non compatibles :

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

Résultats

La mise en page de votre écran utilise désormais l'API Grid pour définir la structure globale bidimensionnelle de la page, tout en intégrant un LazyColumn dans une piste flexible avec un dimensionnement minmax pour recycler efficacement les éléments de la liste et éviter les exceptions d'exécution.

Ressources supplémentaires