O componente "puxar para atualizar" permite que os usuários arrastem para baixo no início do conteúdo de um app para atualizar os dados.
Superfície da API
Use o elemento combinável PullToRefreshBox
para implementar a ação de puxar para atualizar, que
atua como um contêiner para o conteúdo rolável. Os seguintes parâmetros principais
controlam o comportamento e a aparência da atualização:
isRefreshing
: um valor booleano que indica se a ação de atualização está em andamento.onRefresh
: uma função lambda que é executada quando o usuário inicia uma atualização.indicator
: personaliza o indicador que é exibido no recurso de puxar para atualizar.
Exemplo básico
Este snippet demonstra o uso básico de PullToRefreshBox
:
@Composable fun PullToRefreshBasicSample( items: List<String>, isRefreshing: Boolean, onRefresh: () -> Unit, modifier: Modifier = Modifier ) { PullToRefreshBox( isRefreshing = isRefreshing, onRefresh = onRefresh, modifier = modifier ) { LazyColumn(Modifier.fillMaxSize()) { items(items) { ListItem({ Text(text = it) }) } } } }
Pontos principais sobre o código
PullToRefreshBox
envolve umLazyColumn
, que mostra uma lista de strings.PullToRefreshBox
requer os parâmetrosisRefreshing
eonRefresh
.- O conteúdo dentro do bloco
PullToRefreshBox
representa o conteúdo rolável.
Resultado
Este vídeo demonstra a implementação básica de puxar para atualizar do código anterior:
Exemplo avançado: personalizar a cor do indicador
@Composable fun PullToRefreshCustomStyleSample( items: List<String>, isRefreshing: Boolean, onRefresh: () -> Unit, modifier: Modifier = Modifier ) { val state = rememberPullToRefreshState() PullToRefreshBox( isRefreshing = isRefreshing, onRefresh = onRefresh, modifier = modifier, state = state, indicator = { Indicator( modifier = Modifier.align(Alignment.TopCenter), isRefreshing = isRefreshing, containerColor = MaterialTheme.colorScheme.primaryContainer, color = MaterialTheme.colorScheme.onPrimaryContainer, state = state ) }, ) { LazyColumn(Modifier.fillMaxSize()) { items(items) { ListItem({ Text(text = it) }) } } } }
Pontos principais sobre o código
- A cor do indicador é personalizada pelas propriedades
containerColor
ecolor
no parâmetroindicator
. rememberPullToRefreshState()
gerencia o estado da ação de atualização. Use esse estado com o parâmetroindicator
.
Resultado
Este vídeo mostra uma implementação de puxar para atualizar com um indicador colorido:
Exemplo avançado: criar um indicador totalmente personalizado
É possível criar indicadores personalizados complexos usando elementos combináveis e animações.Este snippet demonstra como criar um indicador totalmente personalizado na implementação de puxar para atualizar:
@Composable fun PullToRefreshCustomIndicatorSample( items: List<String>, isRefreshing: Boolean, onRefresh: () -> Unit, modifier: Modifier = Modifier ) { val state = rememberPullToRefreshState() PullToRefreshBox( isRefreshing = isRefreshing, onRefresh = onRefresh, modifier = modifier, state = state, indicator = { MyCustomIndicator( state = state, isRefreshing = isRefreshing, modifier = Modifier.align(Alignment.TopCenter) ) } ) { LazyColumn(Modifier.fillMaxSize()) { items(items) { ListItem({ Text(text = it) }) } } } } // ... @Composable fun MyCustomIndicator( state: PullToRefreshState, isRefreshing: Boolean, modifier: Modifier = Modifier, ) { Box( modifier = modifier.pullToRefreshIndicator( state = state, isRefreshing = isRefreshing, containerColor = PullToRefreshDefaults.containerColor, threshold = PositionalThreshold ), contentAlignment = Alignment.Center ) { Crossfade( targetState = isRefreshing, animationSpec = tween(durationMillis = CROSSFADE_DURATION_MILLIS), modifier = Modifier.align(Alignment.Center) ) { refreshing -> if (refreshing) { CircularProgressIndicator(Modifier.size(SPINNER_SIZE)) } else { val distanceFraction = { state.distanceFraction.coerceIn(0f, 1f) } Icon( imageVector = Icons.Filled.CloudDownload, contentDescription = "Refresh", modifier = Modifier .size(18.dp) .graphicsLayer { val progress = distanceFraction() this.alpha = progress this.scaleX = progress this.scaleY = progress } ) } } } }
Pontos principais sobre o código
- O snippet anterior usou o
Indicator
fornecido pela biblioteca. Esse snippet cria um elemento combinável de indicador personalizado chamadoMyCustomIndicator
. Neste elemento combinável, o modificadorpullToRefreshIndicator
processa o posicionamento e aciona uma atualização. - Como no snippet anterior, a instância
PullToRefreshState
foi extraida, então a mesma instância pode ser transmitida para oPullToRefreshBox
e opullToRefreshModifier
. - A cor do contêiner e o limite de posição são usados da
classe
PullToRefreshDefaults
. Dessa forma, você pode reutilizar o comportamento padrão e o estilo da biblioteca do Material, personalizando apenas os elementos em que você tem interesse. - O
MyCustomIndicator
usaCrossfade
para fazer a transição entre um ícone de nuvem e umCircularProgressIndicator
. O ícone de nuvem é redimensionado conforme o usuário puxa e faz a transição para umCircularProgressIndicator
quando a ação de atualização começa.targetState
usaisRefreshing
para determinar qual estado mostrar (o ícone de nuvem ou o indicador de progresso circular).animationSpec
define uma animaçãotween
para a transição, com uma duração especificada deCROSSFADE_DURATION_MILLIS
.state.distanceFraction
representa o quanto o usuário desceu, variando de0f
(sem puxar) a1f
(puxado totalmente).- O modificador
graphicsLayer
modifica a escala e a transparência.
Resultado
Este vídeo mostra o indicador personalizado do código anterior: