Les aperçus Compose d'Android Studio vous permettent d'inspecter et de vérifier vos composables Wear OS sur différentes tailles d'écran de montre, lunettes rondes et échelles de police directement dans l'IDE, sans déployer votre application sur une montre physique ni sur un émulateur.
Étant donné que les appareils Wear OS sont dotés d'écrans circulaires où les coins rognent le contenu et que les superpositions système telles que TimeText et ScrollIndicator sont incurvées le long du bord de l'écran, il est essentiel de configurer les aperçus spécifiquement pour Wear OS afin de détecter les problèmes de mise en page dès le début.
Configurer les dépendances de l'aperçu
Pour utiliser les annotations d'aperçu et les définitions d'appareils Wear OS Compose, ajoutez les dépendances suivantes au fichier build.gradle.kts de votre module :
dependencies {
// Provides @WearPreview* multipreview annotations
// (such as @WearPreviewDevices and @WearPreviewFontScales)
implementation("androidx.wear.compose:compose-ui-tooling:1.7.0")
// Provides WearDevices constants
// (such as WearDevices.SMALL_ROUND and WearDevices.LARGE_ROUND)
implementation("androidx.wear:wear-tooling-preview:1.0.0")
// Standard Compose preview support and interactive/animation inspection
implementation("androidx.compose.ui:ui-tooling-preview")
debugImplementation("androidx.compose.ui:ui-tooling")
}
Choisir ce que vous souhaitez prévisualiser : écrans ou composants
La façon dont vous configurez un aperçu dépend de ce que vous prévisualisez : un écran complet ou un composant d'UI isolé.
Prévisualiser en plein écran (AppScaffold + ScreenScaffold)
Lorsque vous prévisualisez un écran entier, enveloppez toujours votre composable d'écran dans AppScaffold et ScreenScaffold à l'aide d'une annotation de prévisualisation d'appareil Wear. Cela affiche l'écran circulaire de la montre et garantit que :
TimeTexts'affiche sur le bord supérieur incurvé du cadran.ScrollIndicators'affiche le long de la bordure de droite.EdgeButtonest correctement positionné et fixé au niveau de la courbe inférieure.- La marge intérieure et le découpage circulaire de l'écran reflètent fidèlement le matériel de la montre.
@WearPreviewDevices @Composable fun WorkoutScreenPreview() { MaterialTheme { // AppScaffold provides the top-level TimeText overlay AppScaffold { // WorkoutScreen contains its own ScreenScaffold and content WorkoutScreen( heartRate = 142, elapsedTime = "12:45" ) } } }
Petit rond (192 x 192 dp)
Grand rond (227 x 227 dp)
Prévisualiser des composants isolés
Lorsque vous prévisualisez des composants individuels, tels qu'un Card, un Button ou un chip d'état personnalisé, omettez le paramètre device et utilisez un @Preview standard avec un arrière-plan sombre. Cela permet de s'assurer que les couleurs et le contraste de Wear Material 3 s'affichent correctement sans afficher un cadran circulaire complet :
@Preview( showBackground = true, backgroundColor = 0xFF000000 ) @Composable fun HeartRateCardPreview() { MaterialTheme { HeartRateCard(bpm = 142, zone = "Aerobic") } }
Aperçu isolé du composant (sans cadre d'appareil).
Annotations d'aperçus multiples intégrées
Le package androidx.wear.compose.ui.tooling.preview fournit des annotations intégrées qui configurent automatiquement les arrière-plans sombres (backgroundColor = 0xFF000000, showBackground = true) et les dimensions des appareils connectés circulaires :
| Annotation | Éléments affichés | Quand l'utiliser |
|---|---|---|
@WearPreviewSmallRound |
1 aperçu sur WearDevices.SMALL_ROUND (192 x 192 dp). |
Itération rapide sur la taille d'affichage circulaire la plus contrainte. |
@WearPreviewLargeRound |
1 aperçu sur WearDevices.LARGE_ROUND (227 x 227 dp). |
Inspection de la densité de la mise en page et de l'espacement supplémentaire sur les montres plus grandes. |
@WearPreviewDevices |
Deux aperçus : SMALL_ROUND et LARGE_ROUND. |
Vérification multi-appareil standard pour chaque composable d'écran. |
@WearPreviewFontScales |
6 aperçus sur SMALL_ROUND pour toutes les échelles de police Wear : petite (0.94f), normale (1.0f), moyenne (1.06f), grande (1.12f), plus grande (1.18f) et très grande (1.24f). |
Vérification du retour automatique à la ligne et de l'ellipse du texte, et de l'expansion de la hauteur du bouton. |
Vous pouvez empiler @WearPreviewDevices et @WearPreviewFontScales sur la même fonction d'aperçu pour générer une matrice de test complète :
@WearPreviewDevices @WearPreviewFontScales @Composable fun MessageDetailScreenPreview() { MaterialTheme { AppScaffold { MessageDetailScreen( sender = "Alex", body = "Running 5 mins late!" ) } } }
Annotations d'aperçu personnalisées et caractéristiques matérielles
Si vous avez besoin d'un contrôle plus précis (par exemple, pour tester des dimensions matérielles spécifiques, de longues chaînes localisées ou des combinaisons dans le pire des cas), vous pouvez configurer @Preview directement ou définir vos propres annotations multiprévues personnalisées.
Constantes WearDevices disponibles et caractéristiques matérielles personnalisées
L'objet androidx.wear.tooling.preview.devices.WearDevices fournit des ID d'appareil standards :
WearDevices.SMALL_ROUND("id:wearos_small_round", 192 x 192 dp)WearDevices.LARGE_ROUND("id:wearos_large_round", 227x227 dp)
Pour prévisualiser sur des écrans ronds très grands (comme les montres de 44 à 45 mm ou les modèles Ultra à 240 x 240 dp), transmettez une chaîne spec: personnalisée au paramètre device :
@Preview( name = "XL Round Watch (240dp)", device = "spec:width=240dp,height=240dp,dpi=320,isRound=true", showBackground = true, backgroundColor = 0xFF000000 ) @Composable fun WorkoutScreenXlPreview() { MaterialTheme { AppScaffold { WorkoutScreen(heartRate = 142, elapsedTime = "12:45") } } }
Créer une annotation d'aperçus multiples personnalisée
Pour inspecter un scénario extrême, créez une annotation multi-aperçu personnalisée qui associe le plus petit écran rond à la plus grande échelle de police et à une langue détaillée (comme l'allemand) à un grand écran rond standard :
@Preview( name = "1. Standard Large Round", group = "Layout extremes", device = WearDevices.LARGE_ROUND, backgroundColor = 0xFF000000, showBackground = true ) @Preview( name = "2. Extreme Small Round (Largest Font + German)", group = "Layout extremes", device = WearDevices.SMALL_ROUND, fontScale = 1.24f, locale = "de-rDE", backgroundColor = 0xFF000000, showBackground = true ) annotation class WearPreviewExtremes
1. Grand rond standard
2. Extrêmement petit, rond (police la plus grande + allemand)
Prévisualiser les colonnes défilantes (TransformingLazyColumn)
Par défaut, un TransformingLazyColumn s'initialise avec son premier élément (index = 0) épinglé en haut de l'écran. Toutefois, sur Wear OS, la hauteur et les angles arrondis des éléments (SurfaceTransformation) se transforment à mesure qu'ils approchent des bords incurvés en haut et en bas de l'écran, et le EdgeButton n'apparaît que lorsque l'utilisateur fait défiler l'écran jusqu'en bas.
Pour prévisualiser l'apparence de votre liste lorsque vous la faites défiler à mi-chemin ou en bas :
Étape 1 : Déplacez TransformingLazyColumnState dans votre composable d'écran
Autorisez votre composable d'écran à accepter un paramètre TransformingLazyColumnState avec rememberTransformingLazyColumnState() comme valeur par défaut :
@Composable fun InboxScreen( messages: List<Message>, columnState: TransformingLazyColumnState = rememberTransformingLazyColumnState(), ) { val transformationSpec = rememberTransformationSpec() ScreenScaffold( scrollState = columnState, edgeButton = { EdgeButton(onClick = { /* Compose new */ }) { Text("New message") } } ) { contentPadding -> TransformingLazyColumn( state = columnState, contentPadding = contentPadding, ) { items(messages.size) { index -> Card( onClick = {}, modifier = Modifier .fillMaxWidth() .transformedHeight(this, transformationSpec) .minimumVerticalContentPadding( CardDefaults.minimumVerticalListContentPadding ), transformation = SurfaceTransformation(transformationSpec), ) { Text(messages[index].subject) } } } } }
Étape 2 : Passez initialAnchorItemIndex dans votre @Preview
rememberTransformingLazyColumnState accepte deux paramètres de défilement initial facultatifs :
initialAnchorItemIndex: Int: lorsqu'il est défini sur un index non négatif (par exemple,3), la liste s'initialise avec cet élément centré dans la fenêtre d'affichage de la montre.initialAnchorItemScrollOffset: Int: décalage en pixels facultatif appliqué par rapport à l'élément d'ancrage centré.
Vous pouvez créer des aperçus côte à côte montrant les états Haut, Milieu (avec défilement) et Bas (EdgeButton visible) de la même page :
@WearPreviewLargeRound @Composable fun InboxScreenTopPreview() { MaterialTheme { AppScaffold { // Default (-1): Pinned to top of list (index 0) InboxScreen(messages = sampleMessages) } } } @WearPreviewLargeRound @Composable fun InboxScreenScrolledMiddlePreview() { MaterialTheme { AppScaffold { // Centers item index 3 in the viewport, showing top/bottom item morphing InboxScreen( messages = sampleMessages, columnState = rememberTransformingLazyColumnState( initialAnchorItemIndex = 3 ) ) } } } @WearPreviewLargeRound @Composable fun InboxScreenBottomEdgeButtonPreview() { MaterialTheme { AppScaffold { // Anchors on the last item so the EdgeButton is visible at the bottom InboxScreen( messages = sampleMessages, columnState = rememberTransformingLazyColumnState( initialAnchorItemIndex = sampleMessages.lastIndex ) ) } } }
Haut (par défaut -1)
Moyen (initialAnchorItemIndex = 3)
En bas (EdgeButton développé)
Conseil : Vous pouvez également cliquer sur Démarrer le mode interactif sur n'importe quel
@Previewdans Android Studio pour faire défiler leTransformingLazyColumnen direct avec votre souris ou votre pavé tactile, et inspecter la morphoseSurfaceTransformation, les animations d'entréeEdgeButtonet le mouvementScrollIndicatoren temps réel.
Protection ScrollIndicator lors de la capture de défilement (LocalScrollCaptureInProgress)
Lorsque les outils système de capture de défilement (captures d'écran longues) ou de test de capture d'écran multiframe capturent un TransformingLazyColumn défilant, Compose définit LocalScrollCaptureInProgress.current sur true lors de la capture et de l'assemblage de plusieurs vignettes de fenêtre d'affichage verticalement.
Étant donné que ScreenScaffold ne masque pas automatiquement son scrollIndicator lors de la capture de défilement, la barre de défilement flottante superposée apparaît de manière répétée sur chaque vignette assemblée d'une longue capture d'écran, sauf si vous la protégez explicitement avec !LocalScrollCaptureInProgress.current :
ScreenScaffold( scrollState = columnState, scrollIndicator = { if (!LocalScrollCaptureInProgress.current) { ScrollIndicator(state = columnState) } } ) { contentPadding -> // TransformingLazyColumn content... // ... }