La pagination permet aux utilisateurs de balayer l'écran horizontalement ou verticalement pour passer d'une page distincte en plein écran à une autre sur les appareils Wear OS. Les cas d'utilisation courants incluent le balayage entre les métriques d'entraînement et les commandes multimédias dans une application d'exercice, ou le défilement dans des flux multipages.
Dans Compose pour Wear OS Material 3, HorizontalPagerScaffold et VerticalPagerScaffold coordonnent la mise en page du carrousel, en positionnant automatiquement l'indicateur de page et en gérant les transitions avec TimeText.
Chaque page est encapsulée dans un composable AnimatedPage, qui applique des effets de mise à l'échelle, de morphing des angles arrondis et de voile lorsque les pages passent sur l'écran rond.
L'animation suivante montre comment HorizontalPagerScaffold et AnimatedPage mettent à l'échelle et animent les pages lors des balayages horizontaux :
Hiérarchie de structure pour la pagination
Lorsque vous concevez des mises en page d'écran paginées dans Material 3, que vous balayiez l'écran vers la gauche ou la droite (HorizontalPager) ou vers le haut ou le bas (VerticalPager), utilisez la hiérarchie de composants suivante, du conteneur extérieur au contenu intérieur :
AppScaffold: conteneur le plus externe à la racine de votre application (n'en utiliser qu'un seul par application). Il ancre la superpositionTimeTextglobale afin que l'horloge reste fixe en haut de l'écran lors des transitions de page et des gestes de balayage pour ignorer.HorizontalPagerScaffoldouVerticalPagerScaffold: placé à l'intérieur deAppScaffoldau niveau du sélecteur de page. Il coordonne les transitions entreTimeTextetHorizontalPageIndicatorouVerticalPageIndicator.HorizontalPagerouVerticalPager: conteneur de base du composant Pager qui gère les gestes de balayage, la physique de défilement et l'accrochage de la saisie par dispositif rotatif à l'aide d'unPagerStatepartagé.AnimatedPage: placé dans le lambda de contenu de page du sélecteur de page. Il encapsule chaque page individuelle pour appliquer des animations de transition Material 3 (effets de mise à l'échelle et de voile) en fonction du décalage de la page dansPagerState.ScreenScaffold: placé à l'intérieur deAnimatedPagepour chaque page individuelle. Étant donné que chaque page peut contenir sa propre liste à défilement vertical (comme unTransformingLazyColumn) ou son propreEdgeButton, l'imbrication deScreenScaffolddans chaque page garantit que les indicateurs de défilement vertical, les boutons de bordure etcontentPaddingappartiennent à cette page spécifique et s'animent de manière fluide avec elle.
AppScaffold (1 per app: anchors global TimeText)
└── HorizontalPagerScaffold / VerticalPagerScaffold (manages PageIndicator)
└── HorizontalPager / VerticalPager (manages PagerState & fling behavior)
└── AnimatedPage (applies scaling & scrim transitions per page)
└── ScreenScaffold (1 per page: ScrollIndicator & EdgeButton)
└── Page Content (Column or TransformingLazyColumn)
Implémenter un pager horizontal
Pour implémenter un sélecteur de page horizontal dans Material 3, imbriquez HorizontalPagerScaffold, HorizontalPager, AnimatedPage et ScreenScaffold dans le AppScaffold de votre application.
Utilisez PagerScaffoldDefaults.snapWithSpringFlingBehavior pour flingBehavior afin d'appliquer la physique du mouvement de ressort Material 3 et l'accrochage de page réactif (HighSnapPositionalThreshold). Par défaut, HorizontalPager désactive le défilement de page rotatif (rotaryScrollableBehavior = null), ce qui permet à la couronne rotative ou à la lunette de faire défiler les listes verticales (comme un TransformingLazyColumn) à l'intérieur de la page active.
L'exemple suivant illustre une configuration HorizontalPagerScaffold complète :
@Composable fun HorizontalPagerScaffoldSample(navigateBack: () -> Unit) { AppScaffold { val pagerState = rememberPagerState(pageCount = { 10 }) HorizontalPagerScaffold(pagerState = pagerState) { HorizontalPager( state = pagerState, flingBehavior = PagerScaffoldDefaults.snapWithSpringFlingBehavior( state = pagerState ), ) { page -> AnimatedPage(pageIndex = page, pagerState = pagerState) { ScreenScaffold { Column( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center, ) { Text(text = "Page #$page") Spacer(modifier = Modifier.height(8.dp)) Text(text = "Swipe left and right") if (page == 0) { Spacer(modifier = Modifier.height(16.dp)) Button(onClick = navigateBack) { Text("Exit") } } } } } } } } }
Si une page de votre carrousel horizontal contient un TransformingLazyColumn, créez un rememberTransformingLazyColumnState() distinct dans le champ d'application de cette page et transmettez-le aux ScreenScaffold et TransformingLazyColumn internes :
AppScaffold { val pagerState = rememberPagerState(pageCount = { 10 }) HorizontalPagerScaffold(pagerState = pagerState) { HorizontalPager( state = pagerState, flingBehavior = PagerScaffoldDefaults.snapWithSpringFlingBehavior( state = pagerState ), ) { page -> AnimatedPage(pageIndex = page, pagerState = pagerState) { val columnState = rememberTransformingLazyColumnState() val transformationSpec = rememberTransformationSpec() ScreenScaffold( scrollState = columnState, ) { contentPadding -> TransformingLazyColumn( state = columnState, contentPadding = contentPadding, ) { item { ListHeader( modifier = Modifier .fillMaxWidth() .transformedHeight(this, transformationSpec) .minimumVerticalContentPadding( ListHeaderDefaults.minimumTopListContentPadding ), transformation = SurfaceTransformation(transformationSpec), ) { Text(text = "Pager sample") } } item { Card( modifier = Modifier .fillMaxWidth() .transformedHeight(this, transformationSpec) .minimumVerticalContentPadding( CardDefaults.minimumVerticalListContentPadding ), transformation = SurfaceTransformation(transformationSpec), ) { if (page == 0) { Text(text = "Page #$page. Swipe right") } else { Text(text = "Page #$page. Swipe left and right") } } } } } } } } }
Implémenter un pager vertical
Un sélecteur de page vertical permet aux utilisateurs de balayer l'écran vers le haut ou vers le bas pour passer d'une page à l'autre, ou de parcourir les pages à l'aide du bouton latéral rotatif ou de la lunette de la montre.
Contrairement à HorizontalPager, VerticalPager active par défaut l'accrochage rotatif des pages (RotaryScrollableDefaults.snapBehavior(state)). Transmettez PagerScaffoldDefaults.snapWithSpringFlingBehavior à flingBehavior et encapsulez chaque page dans AnimatedPage et ScreenScaffold :
@Composable fun VerticalPagerScaffoldSample() { AppScaffold { val pagerState = rememberPagerState(pageCount = { 10 }) VerticalPagerScaffold(pagerState = pagerState) { VerticalPager( state = pagerState, flingBehavior = PagerScaffoldDefaults.snapWithSpringFlingBehavior( state = pagerState ), ) { page -> AnimatedPage(pageIndex = page, pagerState = pagerState) { ScreenScaffold { Column( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center, ) { Text(text = "Page #$page") Spacer(modifier = Modifier.height(8.dp)) Text(text = "Swipe up and down") } } } } } } }
Personnaliser le comportement du sélecteur de page
Vous pouvez personnaliser la sensibilité d'accrochage de HorizontalPagerScaffold et VerticalPagerScaffold pour l'adapter aux besoins d'interaction de votre application.
Ajuster la sensibilité de l'accrochage pour les entraînements
Lors d'entraînements ou d'activités à forte intensité où la motricité globale de l'utilisateur est limitée, des contacts accidentels ou de légères rotations de la couronne peuvent changer de page involontairement. Pour ces écrans, configurez votre sélecteur de page avec une faible sensibilité d'accrochage :
PagerDefaults.snapFlingBehaviormaxFlingPages = 0snapPositionalThreshold = PagerScaffoldDefaults.LowSnapPositionalThresholdPour passer la page, vous devez faire glisser votre doigt sur une plus grande partie de l'écran.- Si vous activez l'accrochage de page avec le sélecteur rotatif, définissez
snapSensitivity = RotaryScrollableDefaults.LowSnapSensitivitydansRotaryScrollableDefaults.snapBehaviorpour exiger une rotation plus importante avant l'accrochage à la page suivante.
@Composable fun HorizontalPagerScaffoldWithLowSensitivitySample(navigateBack: () -> Unit) { AppScaffold { val pagerState = rememberPagerState(pageCount = { 3 }) HorizontalPagerScaffold(pagerState = pagerState) { HorizontalPager( state = pagerState, flingBehavior = PagerDefaults.snapFlingBehavior( state = pagerState, maxFlingPages = 0, snapPositionalThreshold = PagerScaffoldDefaults.LowSnapPositionalThreshold, ), rotaryScrollableBehavior = RotaryScrollableDefaults.snapBehavior( pagerState = pagerState, snapSensitivity = RotaryScrollableDefaults.LowSnapSensitivity, ), ) { page -> AnimatedPage(pageIndex = page, pagerState = pagerState) { ScreenScaffold { // Page content } } } } } }
Pour obtenir des exemples d'implémentation complets, consultez Pager.kt dans le dépôt android/snippets et PagerScaffoldSample.kt dans le dépôt AndroidX.