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 o recurso de arrastar para atualizar, que
funciona como um contêiner para seu 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 o sistema desenha ao usar o recurso de arrastar 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
PullToRefreshBoxenvolve umLazyColumn, que mostra uma lista de strings.PullToRefreshBoxrequer os parâmetrosisRefreshingeonRefresh.- O conteúdo dentro do bloco
PullToRefreshBoxrepresenta o conteúdo rolável.
Resultado
Este vídeo demonstra a implementação básica de pull-to-refresh 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
containerColorecolorno parâmetroindicator. - O
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 atuais.Este snippet demonstra como criar um indicador totalmente personalizado na implementação de pull-to-refresh:
@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.pullToRefresh( state = state, isRefreshing = isRefreshing, threshold = PositionalThreshold, onRefresh = { } ), 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
Indicatorfornecido pela biblioteca. Este snippet cria um elemento combinável indicador personalizado chamadoMyCustomIndicator. Nesse elemento combinável, o modificadorpullToRefreshIndicatorprocessa o posicionamento e aciona uma atualização. - Como no snippet anterior, o exemplo extrai a instância
PullToRefreshState. Assim, é possível transmitir a mesma instância paraPullToRefreshBoxepullToRefreshModifier. - O exemplo usa a cor do contêiner e o limite de posição da classe
PullToRefreshDefaults. Assim, você pode reutilizar o comportamento padrão e o estilo da biblioteca Material, personalizando apenas os elementos de seu interesse. - O
MyCustomIndicatorusaCrossfadepara fazer a transição entre um ícone de nuvem e umCircularProgressIndicator. O ícone de nuvem aumenta à medida que o usuário puxa e faz a transição para umCircularProgressIndicatorquando a ação de atualização começa.targetStateusaisRefreshingpara determinar qual estado mostrar (o ícone de nuvem ou o indicador de progresso circular).animationSpecdefine uma animaçãotweenpara a transição, com uma duração especificada deCROSSFADE_DURATION_MILLIS.state.distanceFractionrepresenta o quanto o usuário puxou para baixo, variando de0f(sem puxar) a1f(totalmente puxado).- O modificador
graphicsLayermuda a escala e a transparência.
Resultado
Este vídeo mostra o indicador personalizado do código anterior: