Disposition de la posture sur table avec Grid et mediaQuery

Icône de note 4 étoiles

La posture à plat sur les appareils pliables divise un seul écran en deux zones d'affichage fonctionnelles séparées par le pli physique (ou la charnière). Elle vous permet de placer le contenu principal de votre application (comme un lecteur vidéo ou un canevas de jeu) sur la moitié supérieure, tout en positionnant les éléments interactifs (comme les commandes multimédias ou les pavés de commande) sur la moitié inférieure.

Appareil pliable en position tablette affichant du contenu vidéo sur l'écran supérieur et des commandes de lecture sur l'écran inférieur.
Figure 1. La posture à plat divise le contenu et les commandes interactives sur le pli physique.

Bonnes pratiques

Pour ajouter la compatibilité avec la posture à plat à votre application, utilisez l'API Grid pour définir une mise en page avec deux lignes et une colonne, puis appliquez la requête média de posture de fenêtre à plat.

  • Détecter la posture à plat de manière réactive : utilisez le composable mediaQuery pour observer l'état de l'appareil. Lorsque l'appareil est plié en posture à plat (windowPosture == Posture.Tabletop), modifiez dynamiquement votre mise en page sans avoir à redémarrer l'activité ni à gérer le cycle de vie de manière complexe.
  • Structurer les mises en page avec Grid: en posture à plat, utilisez l'API Grid (2 rows, 1 column) pour séparer clairement le contenu visuel principal dans la ligne supérieure au-dessus du pli et les commandes interactives dans la ligne inférieure en dessous du pli.
  • Exploiter l'indexation Z implicite pour les superpositions : dans les postures standards (non à plat), attribuez plusieurs ID de zone à la même cellule pour superposer les commandes au lecteur. Grid affiche automatiquement les éléments de l'arrière vers l'avant dans leur ordre de déclaration.
  • Assurer des transitions fluides : assurez-vous que l'état et les positions de défilement sont conservés lors du passage entre les mises en page standards en plein écran et la posture à plat.

Ingrédients

  • Grid: conteneur de mise en page adaptatif qui vous permet de positionner des éléments dans des lignes et des colonnes configurables, idéal pour diviser le contenu sur différentes zones de l'écran.
  • mediaQuery: API Jetpack Compose utilisée pour interroger la posture de fenêtre, les classes de taille et les caractéristiques matérielles actuelles de l'application directement dans vos composables.

Étapes

Interrogez la posture de l'appareil à l'aide de mediaQuery(). Lorsque l'appareil est en posture à plat, disposez le contenu de votre application dans une grille verticale avec deux lignes et une colonne, en veillant à ce que le contenu principal reste en haut et que les commandes restent accessibles en bas.

1. Définir les configurations de grille pour le mode à plat

Dans une fonction composable, définissez les ID de zone de mise en page à l'aide d'une énumération et configurez des blocs GridConfigurationScope pour les postures par défaut et à plat.

Dans defaultConfig, les deux zones sont attribuées à la même cellule (row = 1, column = 1). Grid utilise l'indexation Z implicite, où les composables déclarés plus tard dans la mise en page sont affichés au-dessus des précédents, ce qui permet au contrôleur de se superposer au lecteur sans imbrication de conteneur supplémentaire (pour en savoir plus, consultez Superpositions d'éléments d'interface utilisateur avec Grid).

enum class VideoPlayerArea { Player, Controller }

object PlayerGridConfig {
    // Default: Single area layout with overlay (controls on top of player)
    val defaultConfig: GridConfigurationScope.() -> Unit = {
        row(1f)
        column(1f)
        area(areaId = VideoPlayerArea.Player, row = 1, column = 1)
        area(areaId = VideoPlayerArea.Controller, row = 1, column = 1)
    }

    // Tabletop: Two rows splitting content across the fold
    val tabletopConfig: GridConfigurationScope.() -> Unit = {
        row(0.5f)
        row(0.5f)
        column(1f)
        area(areaId = VideoPlayerArea.Player, row = 1, column = 1) // Top half above fold
        area(areaId = VideoPlayerArea.Controller, row = 2, column = 1) // Bottom half below fold
    }
}

2. Détecter la posture à plat et appliquer la configuration à la grille

Utilisez mediaQuery pour sélectionner la configuration active en fonction de windowPosture, transmettez config à Grid et liez le contenu composable aux ID de zone. Déclarer VideoPlayerArea.Player avant VideoPlayerArea.Controller garantit que lorsque les deux partagent une cellule dans defaultConfig, les commandes s'affichent au-dessus du lecteur :

val config = mediaQuery {
    when (windowPosture) {
        Posture.Tabletop -> PlayerGridConfig.tabletopConfig
        else -> PlayerGridConfig.defaultConfig
    }
}

Grid(config = config) {
    Box(
        modifier = Modifier
            .gridItem(areaId = VideoPlayerArea.Player)
    ) {
        // VideoPlayerContent
    }

    Box(
        modifier = Modifier
            .gridItem(areaId = VideoPlayerArea.Controller)
    ) {
        // PlaybackControlsContent
    }
}

Résultats

En combinant mediaQuery et Grid, votre application détecte dynamiquement lorsqu'un appareil pliable est partiellement plié en posture à plat et ajuste automatiquement son interface utilisateur en deux zones d'affichage fonctionnelles divisées par le pli.

Ressources supplémentaires