Pour faire défiler le contenu à gauche et à droite ou de haut en bas, vous pouvez utiliser
la
HorizontalPager
et
VerticalPager
et les composables, respectivement. Ces composables ont des fonctions similaires à
ViewPager
dans la vue
du système d'exploitation. Par défaut, HorizontalPager
occupe toute la largeur de l'écran.
VerticalPager
occupe toute la hauteur, et les bipeurs ne font qu'une page à la fois
en temps réel. Ces valeurs par défaut sont toutes configurables.
HorizontalPager
Pour créer un pager qui défile horizontalement vers la gauche et vers la droite, utilisez
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
Pour créer un pager qui défile vers le haut et vers le bas, utilisez VerticalPager
:
VerticalPager
// Display 10 items val pagerState = rememberPagerState(pageCount = { 10 }) VerticalPager(state = pagerState) { page -> // Our page content Text( text = "Page: $page", modifier = Modifier.fillMaxWidth() ) }
Création différée
Les pages de HorizontalPager
et VerticalPager
sont présentées de manière différée
et disposés et disposés selon les besoins. En tant qu'utilisateur
fait défiler les pages, le composable supprime toutes les pages qui ne sont plus
obligatoire.
Charger plus de pages hors écran
Par défaut, le bipeur ne charge que les pages visibles à l'écran. Pour charger plus de pages
hors écran, définissez beyondBoundsPageCount
sur une valeur supérieure à zéro.
Faire défiler la page jusqu'à un élément
Pour accéder à une page spécifique du pager, créez un
PagerState
à l'aide de
rememberPagerState()
et le transmettre au bipeur en tant que paramètre state
. Vous pouvez appeler
PagerState#scrollToPage()
sur cet état, dans un élément 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") }
Pour créer une animation au niveau de la page, utilisez la méthode
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") }
Recevoir une notification en cas de changement d'état d'une page
PagerState
comporte trois propriétés contenant des informations sur les pages:
currentPage
,
settledPage
,
et
targetPage
.
currentPage
: page la plus proche de la position d'ancrage. Par défaut, l'ancrage se trouve au début de la mise en page.settledPage
: numéro de page lorsqu'aucune animation ni aucun défilement n'est exécuté. Ce est différente de la propriétécurrentPage
, carcurrentPage
est immédiatement mis à jour si la page est suffisamment proche de la position d'ancrage, maissettledPage
reste inchangé jusqu'à ce que toutes les animations aient terminé.targetPage
: position d'arrêt proposée pour un mouvement de défilement.
Vous pouvez utiliser la fonction snapshotFlow
pour observer les modifications apportées à ces variables
et d'y réagir. Par exemple, pour envoyer un événement
d'analyse à chaque modification de page,
vous pouvez effectuer les opérations suivantes:
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") }
Ajouter un indicateur de page
Pour ajouter un indicateur à une page, utilisez l'objet PagerState
afin d'obtenir des informations.
la page sélectionnée parmi celles qui sont disponibles, puis tracez votre
indicateur.
Par exemple, si vous voulez un indicateur de cercle simple, vous pouvez répéter le nombre de
cercles et changer la couleur du cercle selon que la page est sélectionnée, en utilisant
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) ) } }
![Bipeur affichant un indicateur de cercle sous le contenu](https://developer.android.com/static/develop/ui/compose/images/layouts/pager/indicator.png?authuser=8&hl=fr)
Appliquer des effets de défilement au contenu
Un cas d'utilisation courant consiste à utiliser la position de défilement pour appliquer des effets à votre pager.
éléments. Pour connaître la distance qui sépare une page de la page actuellement sélectionnée, vous pouvez
utiliser
PagerState.currentPageOffsetFraction
Vous pouvez ensuite appliquer des effets de transformation à votre contenu en fonction de la distance
de la page sélectionnée.
Par exemple, pour ajuster l'opacité des éléments en fonction de leur distance par rapport à
centrez, modifiez alpha
à l'aide de
Modifier.graphicsLayer
sur un élément du bipeur:
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 } }
Tailles de page personnalisées
Par défaut, HorizontalPager
et VerticalPager
occupent toute la largeur.
à pleine hauteur, respectivement. Vous pouvez définir la variable pageSize
pour qu'elle ait une valeur
Fixed
,
Fill
(par défaut) ou un calcul de taille personnalisé.
Par exemple, pour définir une page 100.dp
à largeur fixe:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, pageSize = PageSize.Fixed(100.dp) ) { page -> // page content }
Pour dimensionner les pages en fonction de la taille de la fenêtre d'affichage, utilisez une taille de page personnalisée.
calcul. Créer un profil personnalisé
PageSize
et diviser la valeur availableSpace
par trois, en tenant compte de l'espacement
entre les éléments:
private val threePagesPerViewport = object : PageSize { override fun Density.calculateMainAxisPageSize( availableSpace: Int, pageSpacing: Int ): Int { return (availableSpace - 2 * pageSpacing) / 3 } }
Marge intérieure du contenu
HorizontalPager
et VerticalPager
acceptent tous deux la modification de la marge intérieure du contenu.
ce qui vous permet d'influencer la taille et l'alignement maximales des pages.
Par exemple, la définition de la marge intérieure start
aligne les pages vers la fin:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(start = 64.dp), ) { page -> // page content }
Définir les marges intérieures start
et end
sur la même valeur pour centrer l'élément
horizontalement:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(horizontal = 32.dp), ) { page -> // page content }
La définition de la marge intérieure end
aligne les pages par rapport au début:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(end = 64.dp), ) { page -> // page content }
Vous pouvez définir les valeurs top
et bottom
pour obtenir des effets similaires pour
VerticalPager
La valeur 32.dp
n'est utilisée qu'à titre d'exemple. vous pouvez définir
chacune des dimensions de marge intérieure sur n'importe quelle valeur.
Personnaliser le comportement de défilement
Les composables HorizontalPager
et VerticalPager
par défaut spécifient comment
les gestes de défilement fonctionnent
avec le pager. Vous pouvez toutefois personnaliser et modifier
les valeurs par défaut, comme pagerSnapDistance
ou flingBehavior
.
Distance du cliché
Par défaut, HorizontalPager
et VerticalPager
définissent le nombre maximal de
pages sur lesquelles un geste vif peut faire défiler l'écran jusqu'à une page à la fois. Pour modifier
ça, définir
pagerSnapDistance
sur le 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) } }
Recommandations personnalisées
- Remarque : Le texte du lien s'affiche lorsque JavaScript est désactivé
- ConstraintLayout dans Compose
- Modificateurs graphiques
- Migrer
CoordinatorLayout
vers Compose