Aby przechodzić między treściami w lewo i w prawo lub w górę i w dół, możesz używać funkcji kompozycyjnych HorizontalPager
i VerticalPager
. Te elementy kompozycyjne mają funkcje podobne do ViewPager
w systemie widoków. Domyślnie HorizontalPager
zajmuje całą szerokość ekranu, VerticalPager
zajmuje całą wysokość, a pagery przewijają tylko 1 stronę. Wszystkie te wartości domyślne można konfigurować.
HorizontalPager
Aby utworzyć pager, który można przewijać w poziomie w lewo i w prawo, użyj funkcji 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ć pager, który przewija się w górę i w dół, użyj funkcji VerticalPager
:
// Display 10 items val pagerState = rememberPagerState(pageCount = { 10 }) VerticalPager(state = pagerState) { page -> // Our page content Text( text = "Page: $page", modifier = Modifier.fillMaxWidth() ) }
Leniwe tworzenie
Zarówno strony HorizontalPager
, jak i VerticalPager
są leniwe i układane w razie potrzeby. Gdy użytkownik przewija strony, funkcja kompozycyjna usuwa wszystkie strony, które nie są już potrzebne.
Wczytaj więcej stron poza ekranem
Domyślnie pager wczytuje tylko strony widoczne na ekranie. Aby wczytywać więcej stron poza ekranem, ustaw beyondBoundsPageCount
na wartość większą od zera.
Przewijanie do elementu w folderze
Aby przewinąć do określonej strony w usłudze pager, utwórz obiekt PagerState
za pomocą metody rememberPagerState()
i prześlij go do pagera jako parametr state
. Możesz wywołać PagerState#scrollToPage()
w tym stanie w 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 utworzyć animację dla strony, 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
zawiera 3 usługi z informacjami o stronach: currentPage
, settledPage
i targetPage
.
currentPage
: strona najbliższa pozycji przyciągania. Domyślnie miejsce przyciągania znajduje się na początku układu.settledPage
: numer strony, na której nie ma animacji ani przewijania. Różni się ona od właściwościcurrentPage
tym, żecurrentPage
aktualizuje się od razu, gdy strona znajdzie się wystarczająco blisko pozycji przyciągania, ale parametrsettledPage
pozostaje taki sam, dopóki nie zostaną zakończone wszystkie animacje.targetPage
: proponowana pozycja zatrzymania 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 na stronie, możesz wykonać 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") }
Dodaj wskaźnik strony
Aby dodać wskaźnik do strony, użyj obiektu PagerState
, aby uzyskać informacje o tym, która strona została wybrana z liczby stron, i narysuj swój wskaźnik niestandardowy.
Jeśli na przykład potrzebujesz prostego wskaźnika okręgu, możesz powtórzyć liczbę kręgów i zmienić kolor okręgu w zależności od tego, czy strona została wybrana, za pomocą funkcji 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) ) } }
Stosuj do treści efekty przewijania
Typowym przypadkiem użycia jest użycie pozycji przewijania do zastosowania efektów do elementów pager. Aby sprawdzić, jak daleko od wybranej obecnie strony znajduje się dana strona, możesz użyć funkcji PagerState.currentPageOffsetFraction
.
Następnie możesz zastosować efekty przekształcenia do treści na podstawie odległości od wybranej strony.
Aby na przykład dostosować przezroczystość elementów w zależności od odległości od ich środka, zmień alpha
za pomocą ciągu Modifier.graphicsLayer
w elemencie wewnątrz pagera:
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 elementy HorizontalPager
i VerticalPager
zajmują pełną szerokość lub pełną wysokość. W zmiennej pageSize
możesz ustawić wartość Fixed
, Fill
(domyślnie) lub niestandardowy sposób obliczania rozmiaru.
Aby na przykład ustawić stronę o stałej szerokości 100.dp
:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, pageSize = PageSize.Fixed(100.dp) ) { page -> // page content }
Aby dopasować rozmiar stron do rozmiaru widocznego obszaru, użyj niestandardowych obliczeń rozmiaru strony. Utwórz obiekt niestandardowy PageSize
i podziel availableSpace
przez trzy, biorąc pod uwagę odstępy między elementami:
private val threePagesPerViewport = object : PageSize { override fun Density.calculateMainAxisPageSize( availableSpace: Int, pageSpacing: Int ): Int { return (availableSpace - 2 * pageSpacing) / 3 } }
Dopełnienie treści
Zarówno HorizontalPager
, jak i VerticalPager
obsługują zmianę dopełnienia treści, co pozwala Ci wpływać na maksymalny rozmiar i wyrównanie stron.
Na przykład ustawienie dopełnienia start
powoduje wyrównanie stron pod koniec:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(start = 64.dp), ) { page -> // page content }
Ustawienie dopełnienia start
i end
na tę samą wartość powoduje wyśrodkowanie elementu w poziomie:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(horizontal = 32.dp), ) { page -> // page content }
Ustawienie dopełnienia end
powoduje wyrównanie strony względem początku:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(end = 64.dp), ) { page -> // page content }
Możesz ustawić wartości top
i bottom
, aby uzyskać podobne efekty w przypadku VerticalPager
. Wartość 32.dp
jest tu użyta tylko jako przykład; każdy wymiar dopełnienia może mieć dowolną wartość.
Dostosowywanie działania przewijania
Domyślne elementy kompozycyjne HorizontalPager
i VerticalPager
określają sposób działania gestów przewijania z pagerem. Możesz jednak dostosować i zmienić wartości domyślne, np. pagerSnapDistance
lub flingBehaviour
.
Odległość przyciągania
Domyślnie HorizontalPager
i VerticalPager
określają maksymalną liczbę stron, które można przesunąć w dół, aby przewinąć stronę do jednej strony naraz. Aby to zmienić, ustaw pagerSnapDistance
w 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) } }
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy JavaScript jest wyłączony
- ConstraintUkład w oknie tworzenia wiadomości
- Modyfikatory graficzne
- Przenieś
CoordinatorLayout
do tworzenia