Para folhear o conteúdo para a esquerda e para a direita ou para cima e para baixo, use
os elementos combináveis
HorizontalPager
e
VerticalPager
, respectivamente. Esses elementos combináveis têm funções semelhantes a
ViewPager
no sistema de
visualização. Por padrão, a HorizontalPager
ocupa toda a largura da tela,
a VerticalPager
ocupa toda a altura e os paginadores mostram apenas uma página por
vez. Todos esses padrões podem ser configurados.
HorizontalPager
Para criar um seletor que role horizontalmente para a esquerda e para a direita, use
HorizontalPager
:
// Display 10 items val pagerState = rememberPagerState(pageCount = { 10 }) HorizontalPager(state = pagerState) { page -> // Our page content Text( text = "Page: $page", modifier = Modifier.fillMaxWidth() ) }
VerticalPager
Para criar um seletor que role para cima e para baixo, use VerticalPager
:
// Display 10 items val pagerState = rememberPagerState(pageCount = { 10 }) VerticalPager(state = pagerState) { page -> // Our page content Text( text = "Page: $page", modifier = Modifier.fillMaxWidth() ) }
Criação lenta
As páginas em HorizontalPager
e VerticalPager
são compostas
lentamente e dispostas quando necessário. À medida que o usuário
rola pelas páginas, o elemento combinável remove as páginas que não são mais
necessárias.
Carregar mais páginas fora da tela
Por padrão, o paginador carrega apenas as páginas visíveis na tela. Para carregar mais páginas
fora da tela, defina beyondBoundsPageCount
como um valor maior que zero.
Rolar até um item na páginação
Para rolar até uma determinada página no seletor, crie um objeto
PagerState
usando
rememberPagerState()
e transmita-o como o parâmetro state
para o seletor. É possível chamar
PagerState#scrollToPage()
nesse estado, dentro de um 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") }
Se você quiser animar a página, use a
função
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") }
Receber notificações sobre mudanças no estado da página
PagerState
tem três propriedades com informações sobre páginas:
currentPage
,
settledPage
e
targetPage
.
currentPage
: a página mais próxima da posição de ajuste. Por padrão, a posição de ajuste fica no início do layout.settledPage
: o número da página quando nenhuma animação ou rolagem está em execução. Isso é diferente da propriedadecurrentPage
, porque ocurrentPage
é atualizado imediatamente se a página estiver perto o suficiente da posição de ajuste, massettledPage
permanece o mesmo até que todas as animações terminem de ser executadas.targetPage
: a posição de parada proposta para um movimento de rolagem.
É possível usar a função snapshotFlow
para observar e reagir às mudanças nessas variáveis. Por exemplo, para enviar um evento de análise em cada mudança de página,
faça o seguinte:
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") }
Adicionar um indicador de página
Para adicionar um indicador a uma página, use o objeto PagerState
para receber informações
sobre qual página é selecionada entre o número de páginas e desenhe seu indicador
personalizado.
Por exemplo, se você quiser um indicador de círculo simples, repita o número de
círculos e mude a cor com base na seleção da página usando
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) ) } }
Aplicar efeitos de rolagem de itens ao conteúdo
Um caso de uso comum é usar a posição de rolagem para aplicar efeitos aos itens
do seletor. Para descobrir a distância entre uma página e a página selecionada no momento, use
PagerState.currentPageOffsetFraction
.
Em seguida, é possível aplicar efeitos de transformação ao conteúdo com base na distância
da página selecionada.
Por exemplo, para ajustar a opacidade dos itens com base na distância deles do
centro, mude o alpha
usando
Modifier.graphicsLayer
em um item dentro do paginador:
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 } }
Tamanhos de página personalizados
Por padrão, HorizontalPager
e VerticalPager
ocupam toda a largura ou
toda a altura, respectivamente. É possível definir a variável pageSize
para ter um
Fixed
,
Fill
(padrão) ou um cálculo de tamanho personalizado.
Por exemplo, para definir uma página de largura fixa de 100.dp
:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, pageSize = PageSize.Fixed(100.dp) ) { page -> // page content }
Para definir o tamanho das páginas com base no tamanho da janela de visualização, use um cálculo
de tamanho de página personalizado. Crie um objeto
PageSize
personalizado e divida o availableSpace
por três, levando em conta o espaçamento
entre os itens:
private val threePagesPerViewport = object : PageSize { override fun Density.calculateMainAxisPageSize( availableSpace: Int, pageSpacing: Int ): Int { return (availableSpace - 2 * pageSpacing) / 3 } }
Padding de conteúdo
HorizontalPager
e VerticalPager
oferecem suporte à alteração do padding do conteúdo,
o que permite influenciar o tamanho máximo e o alinhamento das páginas.
Por exemplo, definir o padding start
alinha as páginas para o fim:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(start = 64.dp), ) { page -> // page content }
Definir o padding start
e end
com o mesmo valor centraliza o item
na horizontal:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(horizontal = 32.dp), ) { page -> // page content }
Definir o padding end
alinha as páginas para o início:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(end = 64.dp), ) { page -> // page content }
É possível definir os valores top
e bottom
para conseguir efeitos semelhantes para
VerticalPager
. O valor 32.dp
é usado aqui apenas como exemplo. Você pode definir
cada uma das dimensões de padding para qualquer valor.
Personalizar o comportamento de rolagem
Os elementos combináveis HorizontalPager
e VerticalPager
padrão especificam como
os gestos de rolagem funcionam com o pager. No entanto, é possível personalizar e mudar
os padrões, como pagerSnapDistance
ou flingBehavior
.
Distância de ajuste
Por padrão, HorizontalPager
e VerticalPager
definem o número máximo de
páginas que um gesto de movimento rápido pode rolar para uma página por vez. Para mudar
isso, defina
pagerSnapDistance
no 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) } }
Recomendados para você
- Observação: o texto do link aparece quando o JavaScript está desativado.
- ConstraintLayout no Compose
- Modificadores gráficos
- Migrar
CoordinatorLayout
para o Compose