Mit den zusammensetzbaren Funktionen HorizontalPager
und VerticalPager
können Sie nach links und rechts bzw. nach oben und unten durch Inhalte blättern. Diese zusammensetzbaren Funktionen haben im Ansichtssystem ähnliche Funktionen wie ViewPager
. Standardmäßig nimmt HorizontalPager
die volle Breite des Bildschirms ein, VerticalPager
die volle Höhe und die Pager öffnen jeweils nur eine Seite. Diese Standardeinstellungen sind konfigurierbar.
HorizontalPager
Verwenden Sie HorizontalPager
, um einen Pager zu erstellen, der horizontal nach links und rechts scrollt:
// Display 10 items val pagerState = rememberPagerState(pageCount = { 10 }) HorizontalPager(state = pagerState) { page -> // Our page content Text( text = "Page: $page", modifier = Modifier.fillMaxWidth() ) }
VerticalPager
Verwenden Sie VerticalPager
, um einen Pager zu erstellen, der nach oben und unten scrollt:
// Display 10 items val pagerState = rememberPagerState(pageCount = { 10 }) VerticalPager(state = pagerState) { page -> // Our page content Text( text = "Page: $page", modifier = Modifier.fillMaxWidth() ) }
Verzögerte Erstellung
Die Seiten in HorizontalPager
und VerticalPager
werden bei Bedarf lazit zusammengestellt und angeordnet. Wenn der Nutzer durch die Seiten scrollt, entfernt die zusammensetzbare Funktion alle Seiten, die nicht mehr benötigt werden.
Weitere Seiten außerhalb des Bildschirms laden
Standardmäßig werden auf dem Pager nur die sichtbaren Seiten geladen. Wenn Sie mehr Seiten außerhalb des sichtbaren Bereichs laden möchten, legen Sie für beyondBoundsPageCount
einen Wert größer als null fest.
Zu einem Element auf der Seite scrollen
Wenn Sie auf dem Pager zu einer bestimmten Seite scrollen möchten, erstellen Sie mit rememberPagerState()
ein PagerState
-Objekt und übergeben Sie es als state
-Parameter an den Pager. Sie können PagerState#scrollToPage()
für diesen Status in einem CoroutineScope
aufrufen:
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") }
Wenn Sie die Seite animieren möchten, verwenden Sie die Funktion 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") }
Benachrichtigungen zu Änderungen des Seitenstatus erhalten
PagerState
hat drei Attribute mit Informationen zu Seiten: currentPage
, settledPage
und targetPage
.
currentPage
: Die Seite, die der Andockposition am nächsten ist. Standardmäßig befindet sich die Andockposition am Anfang des Layouts.settledPage
: Die Seitenzahl, wenn keine Animation oder kein Scrollen ausgeführt wird. Dies unterscheidet sich vom AttributcurrentPage
insofern, alscurrentPage
sofort aktualisiert wird, wenn die Seite nah genug an der Andockposition ist.settledPage
bleibt jedoch gleich, bis alle Animationen ausgeführt wurden.targetPage
: Die vorgeschlagene Stoppposition für eine Scrollbewegung.
Mit der Funktion snapshotFlow
können Sie Änderungen an diesen Variablen beobachten und darauf reagieren. So senden Sie beispielsweise bei jeder Seitenänderung ein Analyseereignis:
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") }
Seitenwechsel hinzufügen
Wenn Sie einer Seite einen Indikator hinzufügen möchten, rufen Sie mit dem Objekt PagerState
Informationen dazu ab, welche Seite aus der Anzahl der Seiten ausgewählt wurde, und zeichnen Sie den benutzerdefinierten Indikator.
Wenn Sie beispielsweise eine einfache Kreisanzeige verwenden möchten, können Sie die Anzahl der Kreise wiederholen und die Kreisfarbe mit pagerState.currentPage
ändern, je nachdem, ob die Seite ausgewählt ist:
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) ) } }
Scrolleffekte von Elementen auf Inhalte anwenden
Ein häufiger Anwendungsfall ist die Verwendung der Scrollposition, um Effekte auf Ihre Pager-Elemente anzuwenden. Mit PagerState.currentPageOffsetFraction
können Sie ermitteln, wie weit eine Seite von der aktuell ausgewählten Seite entfernt ist.
Anschließend können Sie Transformationseffekte basierend auf der Entfernung von der ausgewählten Seite auf Ihre Inhalte anwenden.
Wenn Sie beispielsweise die Deckkraft von Elementen abhängig davon anpassen möchten, wie weit sie von der Mitte entfernt sind, ändern Sie alpha
mit Modifier.graphicsLayer
für ein Element auf dem 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 } }
Benutzerdefinierte Seitengrößen
Standardmäßig nehmen HorizontalPager
und VerticalPager
die volle Breite bzw. Höhe ein. Sie können für die Variable pageSize
entweder Fixed
, Fill
(Standard) oder eine benutzerdefinierte Größenberechnung festlegen.
So legen Sie beispielsweise eine Seite mit fester Breite von 100.dp
fest:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, pageSize = PageSize.Fixed(100.dp) ) { page -> // page content }
Wenn Sie die Größe der Seiten basierend auf der Größe des Darstellungsbereichs anpassen möchten, verwenden Sie eine benutzerdefinierte Berechnung der Seitengröße. Erstellen Sie ein benutzerdefiniertes PageSize
-Objekt und teilen Sie availableSpace
durch drei. Berücksichtigen Sie dabei den Abstand zwischen den Elementen:
private val threePagesPerViewport = object : PageSize { override fun Density.calculateMainAxisPageSize( availableSpace: Int, pageSpacing: Int ): Int { return (availableSpace - 2 * pageSpacing) / 3 } }
Abstände im Inhalt
Sowohl HorizontalPager
als auch VerticalPager
unterstützen das Ändern des Abstands für den Inhalt, sodass Sie die maximale Größe und Ausrichtung von Seiten beeinflussen können.
Wenn Sie beispielsweise den Abstand start
festlegen, werden die Seiten am Ende ausgerichtet:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(start = 64.dp), ) { page -> // page content }
Wenn Sie den Abstand für start
und end
auf denselben Wert festlegen, wird das Element horizontal zentriert:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(horizontal = 32.dp), ) { page -> // page content }
Wenn Sie den Abstand end
festlegen, werden die Seiten am Anfang ausgerichtet:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(end = 64.dp), ) { page -> // page content }
Sie können die Werte top
und bottom
festlegen, um ähnliche Effekte für VerticalPager
zu erzielen. Der Wert 32.dp
wird hier nur als Beispiel verwendet. Sie können für jede Abmessung einen beliebigen Wert festlegen.
Scrollverhalten anpassen
Die standardmäßigen zusammensetzbaren Funktionen HorizontalPager
und VerticalPager
geben an, wie Scrollbewegungen mit dem Pager funktionieren. Sie können die Standardeinstellungen wie pagerSnapDistance
oder flingBehavior
jedoch anpassen und ändern.
Abstand
Standardmäßig legen HorizontalPager
und VerticalPager
die maximale Anzahl von Seiten fest, die mit einer Fingergeste auf eine Seite gescrollt werden können. Wenn Sie dies ändern möchten, legen Sie pagerSnapDistance
für flingBehavior
fest:
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) } }
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- ConstraintLayout in Compose
- Grafikmodifikatoren
CoordinatorLayout
zu Compose migrieren