Per sfogliare i contenuti verso sinistra e destra o verso l'alto e verso il basso, puoi utilizzare rispettivamente i comandi HorizontalPager
e VerticalPager
. Questi composabili hanno funzioni simili a quelle di ViewPager
nel sistema di visualizzazione. Per impostazione predefinita, HorizontalPager
occupa l'intera larghezza dello schermo, VerticalPager
occupa l'intera altezza e i pageri visualizzano una sola pagina alla volta. Questi valori predefiniti sono tutti configurabili.
HorizontalPager
Per creare un cursore che scorra orizzontalmente verso sinistra e destra, utilizza
HorizontalPager
:
HorizontalPager
// Display 10 items val pagerState = rememberPagerState(pageCount = { 10 }) HorizontalPager(state = pagerState) { page -> // Our page content Text( text = "Page: $page", modifier = Modifier.fillMaxWidth() ) }
VerticalPager
Per creare un cursore che scorra verso l'alto e verso il basso, utilizza VerticalPager
:
VerticalPager
// Display 10 items val pagerState = rememberPagerState(pageCount = { 10 }) VerticalPager(state = pagerState) { page -> // Our page content Text( text = "Page: $page", modifier = Modifier.fillMaxWidth() ) }
Creazione lazy
Le pagine di HorizontalPager
e VerticalPager
vengono composte dinamicamente e disposte quando necessario. Man mano che l'utente scorra le pagine, il composable rimuove le pagine non più necessarie.
Caricare altre pagine fuori schermo
Per impostazione predefinita, il selettore di pagine carica solo le pagine visibili sullo schermo. Per caricare più pagine
fuori schermo, imposta beyondBoundsPageCount
su un valore maggiore di zero.
Scorri fino a un elemento nel selettore di pagine
Per scorrere fino a una determinata pagina nel pager, crea un oggetto
PagerState
utilizzando
rememberPagerState()
e passalo come parametro state
al pager. Puoi chiamare
PagerState#scrollToPage()
in questo stato, all'interno di un CoroutineScope
:
val pagerState = rememberPagerState(pageCount = { 10 }) HorizontalPager(state = pagerState) { page -> // Our page content Text( text = "Page: $page", modifier = Modifier .fillMaxWidth() .height(100.dp) ) } // scroll to page val coroutineScope = rememberCoroutineScope() Button(onClick = { coroutineScope.launch { // Call scroll to on pagerState pagerState.scrollToPage(5) } }, modifier = Modifier.align(Alignment.BottomCenter)) { Text("Jump to Page 5") }
Se vuoi animare la pagina, utilizza la funzione
PagerState#animateScrollToPage()
:
val pagerState = rememberPagerState(pageCount = { 10 }) HorizontalPager(state = pagerState) { page -> // Our page content Text( text = "Page: $page", modifier = Modifier .fillMaxWidth() .height(100.dp) ) } // scroll to page val coroutineScope = rememberCoroutineScope() Button(onClick = { coroutineScope.launch { // Call scroll to on pagerState pagerState.animateScrollToPage(5) } }, modifier = Modifier.align(Alignment.BottomCenter)) { Text("Jump to Page 5") }
Ricevere notifiche sulle modifiche dello stato della pagina
PagerState
ha tre proprietà con informazioni sulle pagine:
currentPage
,
settledPage
,
e
targetPage
.
currentPage
: la pagina più vicina alla posizione di aggancio. Per impostazione predefinita, la posizione di aggancio è all'inizio del layout.settledPage
: il numero di pagina quando non è in esecuzione alcuna animazione o scorrimento. Questa proprietà è diversa dalla proprietàcurrentPage
in quantocurrentPage
si aggiorna immediatamente se la pagina è abbastanza vicina alla posizione di aggancio, masettledPage
rimane invariato fino al termine dell'esecuzione di tutte le animazioni.targetPage
: la posizione di arresto proposta per un movimento di scorrimento.
Puoi utilizzare la funzione snapshotFlow
per osservare le modifiche a queste variabili
e reagirvi. Ad esempio, per inviare un evento di analisi a ogni modifica della pagina,
puoi procedere nel seguente modo:
val pagerState = rememberPagerState(pageCount = { 10 }) LaunchedEffect(pagerState) { // Collect from the a snapshotFlow reading the currentPage snapshotFlow { pagerState.currentPage }.collect { page -> // Do something with each page change, for example: // viewModel.sendPageSelectedEvent(page) Log.d("Page change", "Page changed to $page") } } VerticalPager( state = pagerState, ) { page -> Text(text = "Page: $page") }
Aggiungere un indicatore di pagina
Per aggiungere un indicatore a una pagina, utilizza l'oggetto PagerState
per ottenere informazioni sulla pagina selezionata tra il numero di pagine e disegna l'indicatore personalizzato.
Ad esempio, se vuoi un semplice indicatore circolare, puoi ripetere il numero di cerchi e modificarne il colore in base alla selezione della pagina utilizzando pagerState.currentPage
:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, modifier = Modifier.fillMaxSize() ) { page -> // Our page content Text( text = "Page: $page", ) } Row( Modifier .wrapContentHeight() .fillMaxWidth() .align(Alignment.BottomCenter) .padding(bottom = 8.dp), horizontalArrangement = Arrangement.Center ) { repeat(pagerState.pageCount) { iteration -> val color = if (pagerState.currentPage == iteration) Color.DarkGray else Color.LightGray Box( modifier = Modifier .padding(2.dp) .clip(CircleShape) .background(color) .size(16.dp) ) } }

Applicare effetti di scorrimento degli elementi ai contenuti
Un caso d'uso comune è l'utilizzo della posizione di scorrimento per applicare effetti agli elementi del selettore. Per scoprire quanto è distante una pagina da quella attualmente selezionata, puoi
utilizzare
PagerState.currentPageOffsetFraction
.
Puoi quindi applicare effetti di trasformazione ai contenuti in base alla distanza dalla pagina selezionata.
Ad esempio, per regolare l'opacità degli elementi in base alla distanza dal centro, modifica alpha
utilizzando
Modifier.graphicsLayer
su un elemento all'interno del selettore di pagine:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager(state = pagerState) { page -> Card( Modifier .size(200.dp) .graphicsLayer { // Calculate the absolute offset for the current page from the // scroll position. We use the absolute value which allows us to mirror // any effects for both directions val pageOffset = ( (pagerState.currentPage - page) + pagerState .currentPageOffsetFraction ).absoluteValue // We animate the alpha, between 50% and 100% alpha = lerp( start = 0.5f, stop = 1f, fraction = 1f - pageOffset.coerceIn(0f, 1f) ) } ) { // Card content } }
Formati di pagina personalizzati
Per impostazione predefinita, HorizontalPager
e VerticalPager
occupano rispettivamente l'intera larghezza o l'intera altezza. Puoi impostare la variabile pageSize
in modo che abbia un valore Fixed
, Fill
(predefinito) o un calcolo delle dimensioni personalizzato.
Ad esempio, per impostare una pagina con larghezza fissa pari a 100.dp
:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, pageSize = PageSize.Fixed(100.dp) ) { page -> // page content }
Per impostare le dimensioni delle pagine in base alle dimensioni dell'area visibile, utilizza un calcolo personalizzato delle dimensioni delle pagine. Crea un oggetto personalizzato
PageSize
e dividi availableSpace
per tre, tenendo conto della spaziatura
tra gli elementi:
private val threePagesPerViewport = object : PageSize { override fun Density.calculateMainAxisPageSize( availableSpace: Int, pageSpacing: Int ): Int { return (availableSpace - 2 * pageSpacing) / 3 } }
Spaziatura interna dei contenuti
Sia HorizontalPager
sia VerticalPager
supportano la modifica del padding dei contenuti,
che ti consente di influenzare le dimensioni massime e l'allineamento delle pagine.
Ad esempio, l'impostazione del padding start
allinea le pagine verso la fine:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(start = 64.dp), ) { page -> // page content }
Se imposti lo stesso valore sia per lo spazio interno start
sia per quello end
, l'elemento viene centrato orizzontalmente:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(horizontal = 32.dp), ) { page -> // page content }
L'impostazione del padding end
allinea le pagine all'inizio:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(end = 64.dp), ) { page -> // page content }
Puoi impostare i valori top
e bottom
per ottenere effetti simili per
VerticalPager
. Il valore 32.dp
viene utilizzato qui solo come esempio. Puoi impostare ciascuna delle dimensioni di spaziatura su qualsiasi valore.
Personalizzare il comportamento di scorrimento
I componenti composibili HorizontalPager
e VerticalPager
predefiniti specificano il funzionamento dei gesti di scorrimento con il selettore pagine. Tuttavia, puoi personalizzare e modificare i valori predefiniti, come pagerSnapDistance
o flingBehavior
.
Distanza di aggancio
Per impostazione predefinita, HorizontalPager
e VerticalPager
impostano il numero massimo di pagine che un gesto di scorrimento può superare su una pagina alla volta. Per modificarlo, imposta pagerSnapDistance
su flingBehavior
:
val pagerState = rememberPagerState(pageCount = { 10 }) val fling = PagerDefaults.flingBehavior( state = pagerState, pagerSnapDistance = PagerSnapDistance.atMost(10) ) Column(modifier = Modifier.fillMaxSize()) { HorizontalPager( state = pagerState, pageSize = PageSize.Fixed(200.dp), beyondViewportPageCount = 10, flingBehavior = fling ) { PagerSampleItem(page = it) } }
Creare un carosello con avanzamento automatico
Questa sezione descrive come creare un selettore di pagine con avanzamento automatico con indicatori di pagina in Scrittura. La raccolta di elementi scorre automaticamente in orizzontale, ma gli utenti possono anche scorrere manualmente da un elemento all'altro. Se un utente interagisce con il pager, la progressione automatica viene interrotta.
Esempio di base
I seguenti snippet, se combinati, creano un'implementazione di base del selettore con avanzamento automatico con un indicatore visivo, in cui ogni pagina viene visualizzata in un colore diverso:
@Composable fun AutoAdvancePager(pageItems: List<Color>, modifier: Modifier = Modifier) { Box(modifier = Modifier.fillMaxSize()) { val pagerState = rememberPagerState(pageCount = { pageItems.size }) val pagerIsDragged by pagerState.interactionSource.collectIsDraggedAsState() val pageInteractionSource = remember { MutableInteractionSource() } val pageIsPressed by pageInteractionSource.collectIsPressedAsState() // Stop auto-advancing when pager is dragged or one of the pages is pressed val autoAdvance = !pagerIsDragged && !pageIsPressed if (autoAdvance) { LaunchedEffect(pagerState, pageInteractionSource) { while (true) { delay(2000) val nextPage = (pagerState.currentPage + 1) % pageItems.size pagerState.animateScrollToPage(nextPage) } } } HorizontalPager( state = pagerState ) { page -> Text( text = "Page: $page", textAlign = TextAlign.Center, modifier = modifier .fillMaxSize() .background(pageItems[page]) .clickable( interactionSource = pageInteractionSource, indication = LocalIndication.current ) { // Handle page click } .wrapContentSize(align = Alignment.Center) ) } PagerIndicator(pageItems.size, pagerState.currentPage) } }
Punti chiave del codice
- La funzione
AutoAdvancePager
crea una visualizzazione con paginazione orizzontale con avanzamento automatico. Come input accetta un elenco di oggettiColor
, che vengono utilizzati come colori di sfondo per ogni pagina. pagerState
viene creato utilizzandorememberPagerState
, che contiene lo stato del pager.pagerIsDragged
epageIsPressed
monitorano l'interazione degli utenti.- Il
LaunchedEffect
fa avanzare automaticamente il cercapersone ogni due secondi, a meno che l'utente non lo trascini o prema una delle pagine. HorizontalPager
mostra un elenco di pagine, ciascuna con un componibileText
che mostra il numero di pagina. Il modificatore riempie la pagina, imposta il colore di sfondo dapageItems
e rende la pagina selezionabile.
@Composable fun PagerIndicator(pageCount: Int, currentPageIndex: Int, modifier: Modifier = Modifier) { Box(modifier = Modifier.fillMaxSize()) { Row( modifier = Modifier .wrapContentHeight() .fillMaxWidth() .align(Alignment.BottomCenter) .padding(bottom = 8.dp), horizontalArrangement = Arrangement.Center ) { repeat(pageCount) { iteration -> val color = if (currentPageIndex == iteration) Color.DarkGray else Color.LightGray Box( modifier = modifier .padding(2.dp) .clip(CircleShape) .background(color) .size(16.dp) ) } } } }
Punti chiave del codice
- Un composable
Box
viene utilizzato come elemento principale.- All'interno di
Box
, un componibileRow
dispone gli indicatori di pagina in orizzontale.
- All'interno di
- Un indicatore di pagina personalizzato viene visualizzato come una riga di cerchi, in cui ogni
Box
acceso a uncircle
rappresenta una pagina. - Il cerchio della pagina corrente è colorato in
DarkGray
, mentre gli altri cerchi sonoLightGray
. Il parametrocurrentPageIndex
determina quale cerchio viene visualizzato in grigio scuro.
Risultato
Questo video mostra il cursore di avanzamento automatico di base degli snippet precedenti:
Nessun suggerimento al momento.
Prova ad accedere al tuo Account Google.