Per scorrere i contenuti in modo da sinistra e destra oppure verso l'alto e verso il basso, puoi utilizzare rispettivamente gli elementi componibili HorizontalPager
e VerticalPager
. Questi elementi componibili hanno funzioni simili a ViewPager
nel sistema di visualizzazione. Per impostazione predefinita, HorizontalPager
occupa l'intera larghezza dello schermo,
VerticalPager
occupa l'intera altezza e i cercapersone passano solo a una pagina
alla volta. Questi valori predefiniti sono tutti configurabili.
HorizontalPager
Per creare un pager che scorre orizzontalmente verso sinistra e destra, utilizza
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 pager con scorrimento verso l'alto e verso il basso, usa 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 in HorizontalPager
e VerticalPager
vengono composte
pigramente e disposte in modo da essere strutturate quando necessario. Mentre l'utente scorre le pagine, il componibile rimuove tutte le pagine che non sono più necessarie.
Carica altre pagine fuori schermo
Per impostazione predefinita, il pager 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 pager
Per scorrere fino a una determinata pagina nel pager, crea un oggetto PagerState
utilizzando rememberPagerState()
e passalo al pager come parametro state
. 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 allo stato delle pagine
PagerState
ha tre proprietà con informazioni sulle pagine:
currentPage
,
settledPage
e
targetPage
.
currentPage
: la pagina più vicina alla posizione di agganciamento. Per impostazione predefinita, la posizione di agganciamento è all'inizio del layout.settledPage
: il numero della pagina quando non è in corso alcuna animazione o scorrimento. Questa è diversa dalla proprietàcurrentPage
in quantocurrentPage
si aggiorna immediatamente se la pagina è abbastanza vicina alla posizione di agganciamento, mentresettledPage
rimane uguale fino a quando l'esecuzione di tutte le animazioni non è completata.targetPage
: la posizione di interruzione proposta per un movimento di scorrimento.
Puoi utilizzare la funzione snapshotFlow
per osservare le modifiche apportate a queste variabili
e reagire a queste ultime. Ad esempio, per inviare un evento di Analytics a ogni modifica di pagina, puoi:
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") }
Aggiungi un indicatore di pagina
Per aggiungere un indicatore a una pagina, utilizza l'oggetto PagerState
per ottenere informazioni
su quale pagina è selezionata dal numero di pagine e traccia l'indicatore
personalizzato.
Ad esempio, se vuoi un indicatore circolare semplice, puoi ripetere il numero di
cerchi e modificare il colore del cerchio 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 è utilizzare la posizione di scorrimento per applicare effetti agli elementi del cercapersone. Per scoprire quanto è distante una pagina dalla pagina attualmente selezionata, puoi usare PagerState.currentPageOffsetFraction
.
Puoi quindi applicare gli effetti della trasformazione ai tuoi contenuti in base alla distanza dalla pagina selezionata.
Ad esempio, per regolare l'opacità degli elementi in base a quanto sono distanti dal centro, modifica alpha
utilizzando Modifier.graphicsLayer
su un elemento all'interno del pager:
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 } }
Dimensioni di pagina personalizzate
Per impostazione predefinita, HorizontalPager
e VerticalPager
utilizzano rispettivamente l'intera larghezza o
l'altezza completa. Puoi impostare la variabile pageSize
in modo che abbia
Fixed
,
Fill
(valore predefinito) o un calcolo delle dimensioni personalizzate.
Ad esempio, per impostare una pagina a larghezza fissa di 100.dp
:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, pageSize = PageSize.Fixed(100.dp) ) { page -> // page content }
Per ridimensionare le pagine in base a quelle dell'area visibile, usa un calcolo delle dimensioni delle pagine personalizzate. Crea un oggetto PageSize
personalizzato 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
HorizontalPager
e VerticalPager
supportano entrambi la modifica della spaziatura interna dei contenuti,
il che ti consente di influire sulle dimensioni e sull'allineamento massimi delle pagine.
Ad esempio, se imposti la spaziatura interna start
, le pagine vengono allineate verso la fine:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(start = 64.dp), ) { page -> // page content }
Se imposti lo stesso valore per la spaziatura interna start
e end
, l'elemento viene centrato orizzontalmente:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(horizontal = 32.dp), ) { page -> // page content }
Se imposti la spaziatura interna end
, le pagine vengono allineate verso l'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 solo qui come esempio; puoi impostare
ogni dimensione di spaziatura interna su qualsiasi valore.
Personalizza il comportamento di scorrimento
I valori componibili predefiniti HorizontalPager
e VerticalPager
specificano il funzionamento dei gesti di scorrimento con il cercapersone. Tuttavia, puoi personalizzare e modificare
i valori predefiniti, ad esempio pagerSnapDistance
o flingBehavior
.
Distanza di scatto
Per impostazione predefinita, HorizontalPager
e VerticalPager
impostano il numero massimo di pagine
su cui è possibile scorrere un gesto di scorrimento fino a una pagina alla volta. Per modificare
questa impostazione, 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), beyondBoundsPageCount = 10, flingBehavior = fling ) { PagerSampleItem(page = it) } }
Consigliato per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Vincolo Layout in Compose
- Modificatori grafici
- Eseguire la migrazione di
CoordinatorLayout
a Compose