Wenn Sie nach links und rechts oder nach oben und unten durch Inhalte blättern möchten, können Sie die zusammensetzbaren Funktionen HorizontalPager
bzw. VerticalPager
verwenden. Diese zusammensetzbaren Funktionen haben ähnliche Funktionen wie ViewPager
im Ansichtssystem. Standardmäßig nimmt das HorizontalPager
die volle Breite des Bildschirms ein, VerticalPager
die volle Höhe und die Pager wechseln jeweils nur eine Seite. Diese Standardeinstellungen sind alle 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ögertes Erstellen
Seiten in HorizontalPager
und VerticalPager
werden verzögert zusammengesetzt und bei Bedarf neu angelegt. Wenn der Nutzer durch die Seiten scrollt, werden alle nicht mehr benötigten Seiten von der zusammensetzbaren Funktion entfernt.
Weitere nicht sichtbare Seiten laden
Standardmäßig werden vom Pager nur die auf dem Bildschirm sichtbaren Seiten geladen. Wenn Sie mehr Seiten außerhalb des sichtbaren Bereichs laden möchten, setzen Sie beyondBoundsPageCount
auf einen Wert größer als null.
Zu einem Element auf dem Pager scrollen
Wenn Sie zu einer bestimmten Seite im Pager scrollen möchten, erstellen Sie mit rememberPagerState()
ein PagerState
-Objekt und übergeben Sie es als state
-Parameter an den Pager. Sie können für diesen Status PagerState#scrollToPage()
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") }
Benachrichtigung bei Änderungen des Seitenstatus
PagerState
hat drei Properties 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
: Seitennummer, wenn keine Animation oder kein Scrollen ausgeführt wird. Dies unterscheidet sich von der EigenschaftcurrentPage
dadurch, dasscurrentPage
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 können Sie beispielsweise bei jeder Seitenänderung ein Analyseereignis senden:
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") }
Seitenindikator hinzufügen
Wenn Sie einer Seite einen Indikator hinzufügen möchten, verwenden Sie das Objekt PagerState
, um Informationen darüber zu erhalten, 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 Farbe des Kreises ändern, je nachdem, ob die Seite ausgewählt ist. Verwenden Sie dazu 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) ) } }
Scrolleffekte von Elementen auf Inhalte anwenden
Ein häufiger Anwendungsfall ist die Scrollposition, um Effekte auf Ihre Pager-Elemente anzuwenden. Mit PagerState.currentPageOffsetFraction
können Sie herausfinden, wie weit eine Seite von der aktuell ausgewählten Seite entfernt ist.
Anschließend können Sie basierend auf der Entfernung zur ausgewählten Seite Transformationseffekte auf Ihre Inhalte anwenden.
Wenn Sie beispielsweise die Deckkraft von Elementen anpassen möchten, je nachdem, wie weit sie von der Mitte entfernt sind, ändern Sie alpha
mithilfe von 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. die volle Höhe ein. Sie können die Variable pageSize
so festlegen, dass sie entweder Fixed
, Fill
(Standardeinstellung) oder eine benutzerdefinierte Größenberechnung hat.
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 }
Um die Größe der Seiten basierend auf dem Darstellungsbereich anzupassen, 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 zwischen Inhalten
Sowohl HorizontalPager
als auch VerticalPager
unterstützen das Ändern des Inhaltsabstands, sodass Sie die maximale Größe und Ausrichtung von Seiten beeinflussen können.
Wenn Sie beispielsweise den Abstand von start
festlegen, werden die Seiten zum Ende hin ausgerichtet:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(start = 64.dp), ) { page -> // page content }
Wenn Sie die Werte 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 }
Durch Festlegen des Abstands von end
werden die Seiten zum 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 Auswirkungen für VerticalPager
zu erzielen. Der Wert 32.dp
wird hier nur als Beispiel verwendet. Sie können für jede der Innenabstände einen beliebigen Wert festlegen.
Scrollverhalten anpassen
Die standardmäßigen zusammensetzbaren Funktionen HorizontalPager
und VerticalPager
geben an, wie Scrollgesten beim Pager funktionieren. Sie können jedoch die Standardeinstellungen wie pagerSnapDistance
oder flingBehavior
anpassen und ändern.
Abstand zum Andocken
Mit HorizontalPager
und VerticalPager
legen Sie standardmäßig die maximale Anzahl von Seiten fest, bei denen mit einer fließenden Touch-Geste jeweils eine Seite weiterscrollt. Wenn Sie dies ändern möchten, legen Sie pagerSnapDistance
auf 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
zum Schreiben migrieren