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 função "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 o sistema desenha na função "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) }) } } } }
Principais pontos sobre o código
PullToRefreshBoxenvolve umLazyColumn, que mostra uma lista de strings.PullToRefreshBoxrequer os parâmetrosisRefreshingeonRefresh.- O conteúdo no bloco
PullToRefreshBoxrepresenta o conteúdo rolável.
Resultado
Este vídeo demonstra a implementação básica da função "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) }) } } } }
Principais pontos sobre o código
- A cor do indicador é personalizada pelas propriedades
containerColorecolorno parâmetroindicator. rememberPullToRefreshState()gerencia o estado da ação de atualização. Use esse estado em conjunto com o parâmetroindicator.
Resultado
Este vídeo mostra uma implementação da função "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 da função "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.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 } ) } } } }
Principais pontos sobre o código
- O snippet anterior usou o
Indicatorfornecido pela biblioteca. Este snippet cria um elemento combinável de 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, para que você possa transmitir a mesma instância paraPullToRefreshBoxepullToRefreshModifier. - O exemplo usa a cor do contêiner e o limite de posição da classe
PullToRefreshDefaults. Dessa forma, é possível reutilizar o comportamento e o estilo padrão da biblioteca Material, personalizando apenas os elementos de interesse. MyCustomIndicatorusaCrossfadepara fazer a transição entre um ícone de nuvem e umCircularProgressIndicator. O ícone de nuvem aumenta de tamanho à 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 a distância que o usuário puxou para baixo, variando de0f(sem puxar) a1f(totalmente puxado).- O modificador
graphicsLayermodifica a escala e a transparência.
Resultado
Este vídeo mostra o indicador personalizado do código anterior: