Aby przewracać treści w lewo i prawo lub w górę i dół, możesz użyć odpowiednio komponentów HorizontalPager
i VerticalPager
. Te komponenty mają podobne funkcje do komponentów ViewPager
w systemie widoków. Domyślnie HorizontalPager
zajmuje całą szerokość ekranu, VerticalPager
zajmuje całą wysokość, a przeglądarka przenosi tylko jedną stronę naraz. Wszystkie te ustawienia domyślne można konfigurować.
HorizontalPager
Aby utworzyć stronę z przewijaniem poziomym w kierunku lewo-prawo, użyj: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
Aby utworzyć stronę przewijaną w górę i w dół, użyj VerticalPager
:
VerticalPager
// Display 10 items val pagerState = rememberPagerState(pageCount = { 10 }) VerticalPager(state = pagerState) { page -> // Our page content Text( text = "Page: $page", modifier = Modifier.fillMaxWidth() ) }
Tworzenie bezmyślne
Strony w HorizontalPager
i VerticalPager
są komponowane i układane w miarę potrzeby. Gdy użytkownik przewija strony, kompozyt usunął wszystkie strony, które nie są już potrzebne.
Wczytywanie większej liczby stron poza ekranem
Domyślnie przewijanie wczytuje tylko widoczne strony na ekranie. Aby wczytywać więcej stron poza ekranem, ustaw wartość parametru beyondBoundsPageCount
na większą niż zero.
Przewijanie do elementu w pagerze
Aby przewinąć do określonej strony w pagerze, utwórz obiekt PagerState
za pomocą obiektu rememberPagerState()
i przekaż go jako parametr state
do pagera. W tym stanie możesz zadzwonić doPagerState#scrollToPage()
w ramach 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") }
Jeśli chcesz użyć animacji na stronie, użyj funkcji 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") }
Otrzymywanie powiadomień o zmianach stanu strony
PagerState
ma 3 właściwości z informacjami o stronach:
currentPage
,
settledPage
i
targetPage
.
currentPage
: strona najbliższa pozycji przyciągania. Domyślnie pozycja przyciągania znajduje się na początku układu.settledPage
: numer strony, gdy nie działa żadna animacja ani nie jest wykonywane przewijanie. Różnica między właściwościącurrentPage
a polega na tym, żecurrentPage
aktualizuje się natychmiast, gdy strona jest wystarczająco blisko pozycji przyciągania, alesettledPage
pozostaje taka sama, dopóki nie zakończą się wszystkie animacje.targetPage
: proponowana pozycja zatrzymania podczas przewijania.
Za pomocą funkcji snapshotFlow
możesz obserwować zmiany tych zmiennych i na nie reagować. Aby np. wysyłać zdarzenie Analytics przy każdej zmianie strony, wykonaj te czynności:
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") }
Dodawanie wskaźnika strony
Aby dodać wskaźnik do strony, użyj obiektu PagerState
, aby uzyskać informacje o tym, która strona jest wybrana spośród wszystkich stron, i narysuj własny wskaźnik.
Jeśli na przykład chcesz użyć prostego wskaźnika w kształcie koła, możesz powtórzyć liczbę kół i zmienić ich kolor w zależności od tego, czy dana strona jest wybrana, za pomocą: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) ) } }

Stosowanie efektów przewijania elementów do treści
Typowym zastosowaniem jest użycie pozycji przewijania do zastosowania efektów do elementów strony przewijania. Aby sprawdzić, jak daleko jest dana strona od aktualnie wybranej strony, możesz użyć PagerState.currentPageOffsetFraction
.
Następnie możesz zastosować efekty transformacji do treści na podstawie odległości od wybranej strony.
Aby na przykład dostosować przezroczystość elementów w zależności od ich odległości od środka, zmień wartość alpha
za pomocą Modifier.graphicsLayer
w elemencie na stronie:
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 } }
Niestandardowe rozmiary stron
Domyślnie HorizontalPager
i VerticalPager
zajmują odpowiednio całą szerokość lub całą wysokość. Zmienną pageSize
możesz ustawić tak, aby miała wartość Fixed
,
Fill
(domyślnie) lub niestandardowe obliczenie rozmiaru.
Aby na przykład ustawić stałą szerokość strony 100.dp
:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, pageSize = PageSize.Fixed(100.dp) ) { page -> // page content }
Aby dostosować rozmiary stron do rozmiaru widocznego obszaru, użyj niestandardowego obliczenia rozmiaru strony. Utwórz niestandardowy obiekt PageSize
i podziel wartość availableSpace
przez 3, biorąc pod uwagę odstęp między elementami:
private val threePagesPerViewport = object : PageSize { override fun Density.calculateMainAxisPageSize( availableSpace: Int, pageSpacing: Int ): Int { return (availableSpace - 2 * pageSpacing) / 3 } }
wypełnienie treści;
Zarówno HorizontalPager
, jak i VerticalPager
obsługują zmianę wypełnienia treści, co pozwala wpływać na maksymalny rozmiar i wyrównanie stron.
Na przykład ustawienie wypełnienia start
wyrównuje strony do końca:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(start = 64.dp), ) { page -> // page content }
Ustawienie wartości start
i end
na tę samą wartość spowoduje wyśrodkowanie elementu w poziomie:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(horizontal = 32.dp), ) { page -> // page content }
Ustawienie wypełnienia end
wyrównuje strony do początku:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(end = 64.dp), ) { page -> // page content }
Aby uzyskać podobne efekty dla VerticalPager
, możesz ustawić wartości top
i bottom
. Wartość 32.dp
jest tu używana tylko do celów poglądowych. Każdy z wymiarów wypełniania możesz ustawić na dowolną wartość.
Dostosowywanie zachowania przewijania
Domyślne komponenty HorizontalPager
i VerticalPager
określają, jak gesty przewijania działają w przypadku strony. Możesz jednak dostosować i zmienić domyślne wartości, takie jak pagerSnapDistance
lub flingBehavior
.
Odległość przyciągania
Domyślnie HorizontalPager
i VerticalPager
określają maksymalną liczbę stron, które gest przesuwania może przewinąć o jedną stronę naraz. Aby to zmienić, ustaw wartość pagerSnapDistance
w ustawieniu 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) } }
Tworzenie automatycznie przewijającego się pager
W tej sekcji opisaliśmy, jak utworzyć automatycznie przewijany przewijacz z wskaźnikami stron w sekcji Redagowanie. Kolekcja elementów automatycznie przewija się poziomo, ale użytkownicy mogą też ręcznie przeciągać elementy. Jeśli użytkownik wejdzie w interakcję z pagerem, automatyczne przechodzenie do kolejnych stron zostanie wstrzymane.
Przykład podstawowy
Poniższe fragmenty kodu tworzą podstawową implementację automatycznego przewijania strony z wskaźnikiem wizualnym, w której każda strona jest renderowana w innym kolorze:
@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) } }
Najważniejsze informacje o kodzie
- Funkcja
AutoAdvancePager
tworzy widok stron z automatycznym przechodzeniem. Jako dane wejściowe przyjmuje listę obiektówColor
, które są używane jako kolory tła poszczególnych stron. pagerState
jest tworzony za pomocąrememberPagerState
, który przechowuje stan strony.pagerIsDragged
ipageIsPressed
śledzą interakcje użytkowników.LaunchedEffect
automatycznie przesuwa strony co 2 sekundy, chyba że użytkownik przeciągnie stronę lub naciśnie jedną z stron.HorizontalPager
wyświetla listę stron, z których każda ma komponentText
z numerem strony. Modyfikator wypełnia stronę, ustawia kolor tła zpageItems
i czyni ją klikalną.
@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) ) } } } }
Najważniejsze informacje o kodzie
- Jako element główny jest używany komponent
Box
.- Wewnątrz
Box
komponentRow
rozmieszcza wskaźniki stron poziomo.
- Wewnątrz
- Wskaźnik strony niestandardowej jest wyświetlany jako rząd okręgów, z których każdy
Box
przycięty docircle
reprezentuje stronę. - Krąg bieżącej strony jest oznaczony kolorem
DarkGray
, a inneLightGray
. ParametrcurrentPageIndex
określa, które koło będzie renderowane w ciemnoszarym kolorze.
Wynik
Ten film pokazuje podstawowy automatycznie przesuwający się wyświetlacz z poprzednich fragmentów:
Obecnie nie ma rekomendacji.
Zaloguj się na swoje konto Google.