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 jak 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
// 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
:
// 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 tą właściwością polega na tym, żecurrentPage
aktualizuje się natychmiast, gdy strona jest wystarczająco blisko pozycji zaczepienia, alesettledPage
pozostaje taka sama, dopóki nie zakończą się wszystkie animacje.targetPage
: proponowana pozycja zatrzymania dla ruchu przewijania.
Za pomocą funkcji snapshotFlow
możesz obserwować zmiany tych zmiennych i na nie reagować. Aby na przykład wysyłać zdarzenie Analytics po 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 dowiedzieć się, 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) } }
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy obsługa JavaScript jest wyłączona
- ConstraintLayout w Compose
- Modyfikatory graficzne
- Migracja
CoordinatorLayout
do tworzenia wiadomości