Mise en page de carte classique large avec grille

Icône de note de quatre étoiles

Les consignes de conception d'applications pour TV définissent une variante de carte appelée « Carte classique large », qui affiche une image et son bloc de contenu descriptif côte à côte. Lorsque vous créez des mises en page bidimensionnelles complexes pour les écrans de télévision, l'utilisation d'un positionnement traditionnel basé sur les coordonnées ou de conteneurs Row et Column profondément imbriqués peut rendre votre code difficile à lire, à maintenir et à refactoriser. La carte classique large est un cas d'utilisation idéal pour l'API Grid de Jetpack Compose, qui vous aide à structurer clairement les éléments côte à côte à l'aide de zones de mise en page bidimensionnelles sémantiques et définies par l'utilisateur.

Spécification du composant de fiche classique large montrant cinq zones de mise en page nommées : image, titre, sous-titre, description et texte supplémentaire.
Image 1. Carte classique large avec cinq zones nommées : zone d'image et quatre zones de texte dans le bloc de contenu.

Bonnes pratiques

Implémentez la mise en page de la carte avec Grid. L'utilisation du conteneur Grid améliore la lisibilité du code en dissociant les dimensions physiques de la mise en page du placement des éléments enfants. Plutôt que de vous appuyer sur des index de piste exacts, définissez des zones nommées sémantiques avec la fonction area et placez les composables enfants avec le modificateur gridItem. Combinez le dimensionnement flexible des pistes, tel que GridTrackSize.Auto et minmax(0.dp, 1.fr), avec des espacements de piste exacts (gap(row = 8.dp, column = 16.dp)) pour organiser clairement et de manière robuste les composants de carte complexes côte à côte.

Ingrédients

  • Grid: mise en page de conteneur bidimensionnel dans Jetpack Compose qui organise les composables enfants en lignes et en colonnes en fonction d'un lambda de configuration.
  • gridItem: extension Modifier qui associe un élément d'interface utilisateur enfant à un areaId nommé spécifique dans une mise en page Grid.
  • area : fonction DSL de configuration dans GridConfigurationScope qui mappe un areaId sémantique à des étendues ou des plages de lignes et de colonnes spécifiques.
  • Card: composable de conteneur Material Design qui regroupe les éléments d'interface utilisateur et le style associés.
  • GridTrackSize.MinMax: propriété de dimensionnement de piste qui définit des limites flexibles (min et max) pour les dimensions de ligne ou de colonne.
  • GridTrackSize.Auto : propriété de dimensionnement de piste qui dimensionne automatiquement la piste de ligne ou de colonne pour l'adapter à son contenu (column(GridTrackSize.Auto)).
  • gap: fonction de configuration qui spécifie l'espacement vertical (row) et horizontal (column) entre les pistes de la grille.

Étapes

Définissez les identifiants de zone, configurez les pistes et les zones de la grille, puis placez les composables enfants.

1. Définir des identifiants de zone sémantiques

Commencez par créer une représentation de type sécurisé des régions dans votre mise en page de carte classique large. Une classe enum évite les erreurs de frappe dans les chaînes et assure la sécurité au moment de la compilation lors du mappage des pistes et du placement des éléments enfants.

enum class CardArea {
    Image,
    Title,
    Subtitle,
    Description,
    ExtraText,
}

2. Configurer les pistes de grille bidimensionnelles et les zones nommées

Dans le lambda config de votre composable Grid, définissez les colonnes et les lignes qui composent la structure de la carte. Utilisez GridTrackSize.Auto pour la colonne d'image afin qu'elle s'adapte correctement à la largeur de la miniature. Utilisez minmax(0.dp, 1.fr) pour la colonne de contenu afin qu'elle s'étende de manière flexible sur la largeur restante de la carte. Spécifiez l'espacement des pistes avec gap(row = 8.dp, column = 16.dp). Mappez vos identifiants CardArea à leurs coordonnées de piste physiques à l'aide de la fonction area.

Grid(
    config = {
        // Define columns: left column for image, right for content
        column(GridTrackSize.Auto)
        column(minmax(0.dp, 1.fr))

        // Define row tracks for the vertical content stack
        row(GridTrackSize.Auto)
        row(GridTrackSize.Auto)
        row(GridTrackSize.Auto)
        row(GridTrackSize.Auto)

        // Map semantic identifiers to grid coordinates and spans
        area(CardArea.Image, row = 1, column = 1, rowSpan = 4)
        area(CardArea.Title, row = 1, column = 2)
        area(CardArea.Subtitle, row = 2, column = 2)
        area(CardArea.Description, row = 3, column = 2)
        area(CardArea.ExtraText, row = 4, column = 2)

        gap(row = 8.dp, column = 16.dp)
    }
) {
    // Child elements placed in Step 3
}

3. Placer les composables enfants à l'aide du modificateur gridItem

Une fois vos pistes et vos zones configurées, placez chaque élément d'interface utilisateur enfant uniquement par intention sémantique à l'aide du modificateur gridItem. Vous pouvez déclarer des composables enfants dans n'importe quel ordre. Le conteneur Grid positionne automatiquement chaque élément directement dans la région bidimensionnelle qui lui est attribuée.

@Composable
fun WideClassicCard(
    imageContent: @Composable () -> Unit,
    title: String,
    subtitle: String,
    description: String,
    extraText: String,
    modifier: Modifier = Modifier,
) {
    Card(modifier = modifier) {
        Grid(
            config = {
                // Define columns: left column for image, right for content
                column(GridTrackSize.Auto)
                column(minmax(0.dp, 1.fr))

                // Define row tracks for the vertical content stack
                row(GridTrackSize.Auto)
                row(GridTrackSize.Auto)
                row(GridTrackSize.Auto)
                row(GridTrackSize.Auto)

                // Map semantic identifiers to grid coordinates and spans
                area(CardArea.Image, row = 1, column = 1, rowSpan = 4)
                area(CardArea.Title, row = 1, column = 2)
                area(CardArea.Subtitle, row = 2, column = 2)
                area(CardArea.Description, row = 3, column = 2)
                area(CardArea.ExtraText, row = 4, column = 2)

                gap(row = 8.dp, column = 16.dp)
            },
        ) {
            Box(modifier = Modifier.gridItem(CardArea.Image)) {
                imageContent()
            }
            Text(
                text = title,
                style = MaterialTheme.typography.titleLarge,
                modifier = Modifier
                    .gridItem(CardArea.Title)
                    .padding(top = 16.dp, end = 16.dp),
            )

            Text(
                text = subtitle,
                style = MaterialTheme.typography.titleMedium,
                modifier = Modifier
                    .gridItem(CardArea.Subtitle)
                    .padding(end = 16.dp),
            )

            Text(
                text = description,
                style = MaterialTheme.typography.bodyMedium,
                modifier = Modifier
                    .gridItem(CardArea.Description)
                    .padding(end = 16.dp),
            )

            Text(
                text = extraText,
                style = MaterialTheme.typography.labelSmall,
                modifier = Modifier
                    .gridItem(CardArea.ExtraText)
                    .padding(bottom = 16.dp, end = 16.dp),
            )
        }
    }
}

Résultats

En organisant votre carte classique large avec Grid et des zones nommées, vous obtenez une séparation claire entre les pistes de mise en page physiques, les coordonnées de zone et le placement des composables enfants. Cette structure rend votre mise en page lisible et facile à gérer tout en respectant les consignes de conception d'applications pour TV pour les composants de miniature et de description côte à côte.

Ressources supplémentaires