La paginazione consente agli utenti di scorrere orizzontalmente o verticalmente tra pagine distinte a schermo intero sui dispositivi Wear OS. I casi d'uso comuni includono lo scorrimento tra le metriche dell'allenamento e i controlli multimediali in un'app di allenamento o la navigazione in flussi di più pagine.
In Compose per Wear OS Material 3, HorizontalPagerScaffold e
VerticalPagerScaffold coordinano il layout del pager, posizionando automaticamente
l'indicatore di pagina e gestendo le transizioni con TimeText.
Ogni pagina è racchiusa in un componente componibile AnimatedPage, che applica
effetti di ridimensionamento, morphing degli angoli arrotondati e scrim durante la transizione delle pagine
sul display rotondo.
La seguente animazione mostra come HorizontalPagerScaffold e AnimatedPage
scalano e animano le pagine durante gli scorrimenti orizzontali:
Struttura della gerarchia per la paginazione
Quando progetti layout di schermate impaginate in Material 3, sia che scorri
verso sinistra o destra (HorizontalPager) o verso l'alto o il basso (VerticalPager), utilizza la
seguente gerarchia dei componenti dal contenitore esterno ai contenuti interni:
AppScaffold: il contenitore più esterno nella radice dell'app (utilizzane solo uno per app). Ancora l'overlay globaleTimeTextin modo che l'orologio rimanga fermo nella parte superiore dello schermo durante le transizioni di pagina e i gesti di scorrimento per chiudere.HorizontalPagerScaffoldoVerticalPagerScaffold: inserito all'interno diAppScaffolda livello di paginazione. Coordina le transizioni traTimeTexteHorizontalPageIndicatoroVerticalPageIndicator.HorizontalPageroVerticalPager: il contenitore del pager di base che gestisce i gesti di scorrimento, la fisica di scorrimento rapido e l'input rotativo utilizzando unPagerStatecondiviso.AnimatedPage: inserito all'interno della lambda dei contenuti della pagina del pager. Esegue il wrapping di ogni singola pagina per applicare le animazioni di transizione Material 3 (effetti di ridimensionamento e velatura) in base all'offset della pagina inPagerState.ScreenScaffold: inserito all'interno diAnimatedPageper ogni singola pagina. Poiché ogni pagina può contenere un proprio elenco scorrevole verticalmente (ad esempio unTransformingLazyColumn) o un proprioEdgeButton, l'incorporamento diScreenScaffoldall'interno di ogni pagina garantisce che gli indicatori di scorrimento verticale, i pulsanti sui bordi econtentPaddingappartengano a quella pagina specifica e si animino in modo fluido.
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)
Implementare un pager orizzontale
Per implementare un pager orizzontale in Material 3, annida HorizontalPagerScaffold,
HorizontalPager, AnimatedPage e ScreenScaffold all'interno di AppScaffold dell'app.
Utilizza PagerScaffoldDefaults.snapWithSpringFlingBehavior per
flingBehavior per applicare la fisica del movimento a molla di Material 3 e lo snapping reattivo della pagina (HighSnapPositionalThreshold). Per impostazione predefinita, HorizontalPager disattiva
lo scorrimento della pagina rotante (rotaryScrollableBehavior = null), consentendo all'input della corona rotante
o della ghiera di scorrere gli elenchi verticali (ad esempio un
TransformingLazyColumn) all'interno della pagina attiva.
Il seguente esempio mostra una configurazione HorizontalPagerScaffold completa:
@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") } } } } } } } } }
Se una pagina all'interno del pager orizzontale contiene un TransformingLazyColumn,
crea un rememberTransformingLazyColumnState() separato all'interno dell'ambito
della pagina e passalo ai ScreenScaffold e TransformingLazyColumn interni:
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") } } } } } } } } }
Implementare un pager verticale
Un pager verticale consente agli utenti di scorrere verso l'alto e verso il basso tra le pagine o di sfogliarle utilizzando il pulsante laterale rotante o la ghiera dello smartwatch.
A differenza di HorizontalPager, VerticalPager attiva l'allineamento rotatorio delle pagine per impostazione predefinita (RotaryScrollableDefaults.snapBehavior(state)). Passa PagerScaffoldDefaults.snapWithSpringFlingBehavior a flingBehavior e racchiudi ogni pagina in AnimatedPage e 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") } } } } } } }
Personalizzare il comportamento del cercapersone
Puoi personalizzare la sensibilità dello snapping di HorizontalPagerScaffold e
VerticalPagerScaffold in base alle esigenze di interazione della tua app.
Regolare la sensibilità dello snap per gli allenamenti
Durante gli allenamenti o le attività con movimenti ampi in cui il controllo motorio dell'utente è limitato, tocchi accidentali o leggere rotazioni della corona possono cambiare pagina involontariamente. Per queste schermate, configura il pager con una sensibilità di scatto bassa:
- Passa
PagerDefaults.snapFlingBehaviorconmaxFlingPages = 0esnapPositionalThreshold = PagerScaffoldDefaults.LowSnapPositionalThresholdpertanto è necessario trascinare deliberatamente su una porzione più ampia dello schermo per girare la pagina. - Se attivi lo scorrimento rotatorio delle pagine, imposta
snapSensitivity = RotaryScrollableDefaults.LowSnapSensitivityinRotaryScrollableDefaults.snapBehaviorper richiedere una rotazione maggiore prima di passare alla pagina successiva.
@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 } } } } } }
Per implementazioni di esempio complete, consulta Pager.kt nel repository android/snippets e PagerScaffoldSample.kt nel repository AndroidX.