Vous avez besoin de différents types d'informations, tels que les fonctionnalités de l'appareil et l'état de l'application, pour mettre à jour la mise en page de votre application. La largeur et la hauteur de la fenêtre sont les informations les plus couramment utilisées. Vous pouvez également vous référer aux informations suivantes :
- Position de la fenêtre
- Précision des périphériques de pointage
- Type de clavier
- Indique si l'appareil est compatible avec la caméra et le micro
- Distance entre un utilisateur et l'écran de l'appareil
Comme les informations sont mises à jour de manière dynamique, vous devez les surveiller et déclencher une recomposition en cas de mise à jour.
La fonction mediaQuery abstrait les détails de la récupération des informations
et vous permet de vous concentrer sur la définition de la condition pour déclencher les mises à jour de la mise en page.
L'exemple suivant remplace la mise en page par TabletopLayout lorsque la position pliable est "tablette" :
@Composable fun VideoPlayer( // ... ) { // ... if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) { TabletopLayout() } else { FlatLayout() } // ... }
Activer la fonction mediaQuery
Pour activer la fonction mediaQuery,
définissez l'attribut isMediaQueryIntegrationEnabled de
l'objet ComposeUiFlags sur true :
class MyApplication : Application() { override fun onCreate() { ComposeUiFlags.isMediaQueryIntegrationEnabled = true super.onCreate() } }
Définir une condition avec des paramètres
Vous pouvez définir une condition en tant que lambda
évalué dans UiMediaScope.
La fonction mediaQuery évalue la condition en fonction de l'état actuel et des fonctionnalités de l'appareil.
La fonction renvoie une valeur booléenne. Vous pouvez donc déterminer la mise en page avec des branches conditionnelles comme une expression if.
Le tableau 1 décrit les paramètres disponibles dans UiMediaScope.
| Paramètre | Type de valeur | Description |
|---|---|---|
windowWidth |
Dp |
Largeur actuelle de la fenêtre en dp. |
windowHeight |
Dp |
Hauteur actuelle de la fenêtre en dp. |
windowPosture |
UiMediaScope.Posture |
Position actuelle de la fenêtre de l'application. |
pointerPrecision |
UiMediaScope.PointerPrecision |
Précision maximale des périphériques de pointage disponibles. |
keyboardKind |
UiMediaScope.KeyboardKind |
Type de clavier disponible ou connecté. |
hasCamera |
Boolean |
Indique si l'appareil est compatible avec la caméra. |
hasMicrophone |
Boolean |
Indique si l'appareil est compatible avec le micro. |
viewingDistance |
UiMediaScope.ViewingDistance |
Distance type entre l'utilisateur et l'écran de l'appareil. |
Un objet UiMediaScope résout les valeurs des paramètres.
La fonction mediaQuery utilise LocalUiMediaScope.current
pour accéder à l'objet UiMediaScope,
qui représente les fonctionnalités et le contexte actuels de l'appareil.
Cet objet est mis à jour de manière dynamique lorsque des modifications sont apportées, par exemple lorsque l'utilisateur modifie la position de l'appareil.
La fonction mediaQuery évalue ensuite le lambda query avec l'objet UiMediaScope mis à jour et renvoie une valeur booléenne.
Par exemple, l'extrait de code suivant choisit entre TabletopLayout et FlatLayout en fonction de la valeur du paramètre windowPosture.
@Composable fun VideoPlayer( // ... ) { // ... if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) { TabletopLayout() } else { FlatLayout() } // ... }
Prendre une décision en fonction de la taille de la fenêtre
Les classes de taille de fenêtre sont un ensemble de points d'arrêt de fenêtre d'affichage définis
qui permettent de concevoir, de développer et de tester des mises en page adaptatives.
Vous pouvez comparer les deux paramètres représentant la taille actuelle de la fenêtre avec le seuil défini dans les classes de taille de fenêtre.
L'exemple suivant modifie le nombre de volets en fonction de la largeur de la fenêtre.
WindowSizeClass classe comporte des constantes pour les seuils
des classes de taille de fenêtre (figure 1).
La derivedMediaQuery fonction évalue le query lambda
et encapsule le résultat dans un derivedStateOf.
Comme windowWidth et windowHeight peuvent être mis à jour fréquemment, appelez la fonction derivedMediaQuery au lieu de la fonction mediaQuery lorsque vous faites référence à ces paramètres dans le lambda query.
val narrowerThanMedium by derivedMediaQuery { windowWidth < WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND.dp } val narrowerThanExpanded by derivedMediaQuery { windowWidth < WindowSizeClass.WIDTH_DP_EXPANDED_LOWER_BOUND.dp } when { narrowerThanMedium -> SinglePaneLayout() narrowerThanExpanded -> TwoPaneLayout() else -> ThreePaneLayout() }
Mettre à jour la mise en page en fonction de la position de la fenêtre
Le paramètre windowPosture décrit la position actuelle de la fenêtre en tant qu'objet UiMediaScope.Posture.
Vous pouvez vérifier la position actuelle en comparant le paramètre
aux valeurs définies dans la UiMediaScope.Posture classe.
L'exemple suivant modifie la mise en page en fonction de la position de la fenêtre :
when { mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop } -> TabletopLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Book } -> BookLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Flat } -> FlatLayout() }
Vérifier la précision du périphérique de pointage disponible
Un périphérique de pointage haute précision permet aux utilisateurs de pointer précisément un élément d'interface utilisateur. La précision d'un périphérique de pointage dépend du type d'appareil.
Le paramètre pointerPrecision décrit la précision des périphériques de pointage disponibles, tels qu'une souris et un écran tactile.
Quatre valeurs sont définies dans la classe UiMediaScope.PointerPrecision :
Fine, Coarse, Blunt et None.
None signifie qu'aucun périphérique de pointage n'est disponible.
La précision est classée de la plus élevée à la plus faible dans cet ordre : Fine, Coarse et Blunt.
Si plusieurs périphériques de pointage sont disponibles et que leur précision est différente, le paramètre est résolu avec la plus élevée.
Par exemple, s'il existe deux périphériques de pointage (un périphérique de précision Fine et un périphérique de précision Blunt), Fine est la valeur du paramètre pointerPrecision.
L'exemple suivant affiche un bouton plus grand lorsque l'utilisateur utilise un périphérique de pointage de faible précision :
if (mediaQuery { pointerPrecision == UiMediaScope.PointerPrecision.Blunt }) { LargeSizeButton() } else { NormalSizeButton() }
Vérifier le type de clavier disponible
Le paramètre keyboardKind représente le type de claviers disponibles :
Physical, Virtual et None.
Si un clavier à l'écran s'affiche et qu'un clavier matériel est disponible en même temps, le paramètre est résolu en tant que Physical.
Si aucun des deux n'est détecté, None est la valeur du paramètre.
L'exemple suivant affiche un message suggérant aux utilisateurs de connecter un clavier lorsqu'aucun clavier n'est détecté :
if (mediaQuery { keyboardKind == UiMediaScope.KeyboardKind.None }) { SuggestKeyboardConnect() }
Vérifier si l'appareil est compatible avec la caméra et le micro
Certains appareils ne sont pas compatibles avec les caméras ni les micros.
Vous pouvez vérifier si l'appareil est compatible avec une caméra et un micro à l'aide des paramètres hasCamera et hasMicrophone.
L'exemple suivant affiche des boutons à utiliser avec la caméra et le micro lorsque l'appareil est compatible avec ces fonctionnalités :
Row { OutlinedTextField(state = rememberTextFieldState()) // Show the MicButton when the device supports a microphone. if (mediaQuery { hasMicrophone }) { MicButton() } // Show the CameraButton when the device supports a camera. if (mediaQuery { hasCamera }) { CameraButton() } }
Ajuster l'interface utilisateur en fonction de la distance de visualisation estimée
La distance de visualisation est un facteur qui permet de déterminer la mise en page.
Si l'utilisateur utilise l'application à distance, il s'attend à ce que le texte et les éléments d'interface utilisateur soient plus grands.
Le paramètre viewingDistance fournit une estimation de la distance de visualisation en fonction du type d'appareil et de son contexte d'utilisation type.
Trois valeurs sont définies dans la classe UiMediaScope.ViewingDistance :
Near, Medium et Far.
Near signifie que l'écran est à proximité, et Far signifie que l'appareil est visualisé à distance.
L'exemple suivant augmente la taille de la police lorsque la distance de visualisation est Far ou Medium :
val fontSize = when { mediaQuery { viewingDistance == UiMediaScope.ViewingDistance.Far } -> 20.sp mediaQuery { viewingDistance == UiMediaScope.ViewingDistance.Medium } -> 18.sp else -> 16.sp }
Prévisualiser un composant d'interface utilisateur
Vous pouvez appeler les fonctions mediaQuery et derivedMediaQuery dans les fonctions composables pour prévisualiser les composants d'interface utilisateur.
L'extrait de code suivant choisit entre TabletopLayout et FlatLayout en fonction de la valeur du paramètre windowPosture.
Pour prévisualiser le TabletopLayout, le paramètre windowPosture doit être
UiMediaScope.Posture.Tabletop.
when { mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop } -> TabletopLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Book } -> BookLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Flat } -> FlatLayout() }
Les fonctions mediaQuery et derivedMediaQuery évaluent
le lambda query donné dans un objet UiMediaScope,
qui est fourni en tant que LocalUiMediaScope.current.
Vous pouvez le remplacer en procédant comme suit :
- Activer la fonction
mediaQuery. - Définissez un objet personnalisé qui implémente l'interface
UiMediaScope. - Définissez l'objet personnalisé sur le
LocalUiMediaScopeavec la fonctionCompositionLocalProvider. - Appelez le composable pour prévisualiser dans le lambda de contenu de la fonction
CompositionLocalProvider.
Vous pouvez prévisualiser TabletopLayout avec l'exemple suivant :
@Preview @Composable fun PreviewLayoutForTabletop() { // Step 1: Enable the mediaQuery function ComposeUiFlags.isMediaQueryIntegrationEnabled = true val currentUiMediaScope = LocalUiMediaScope.current // Step 2: Define a custom object implementing the UiMediaScope interface. // The object overrides the windowPosture parameter. // The resolution of the remaining parameters is deferred to the currentUiMediaScope object. val uiMediaScope = remember(currentUiMediaScope) { object : UiMediaScope by currentUiMediaScope { override val windowPosture: UiMediaScope.Posture = UiMediaScope.Posture.Tabletop } } // Step 3: Set the object to the LocalUiMediaScope. CompositionLocalProvider(LocalUiMediaScope provides uiMediaScope) { // Step 4: Call the composable to preview. when { mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop } -> TabletopLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Book } -> BookLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Flat } -> FlatLayout() } } }