El componente de deslizar para actualizar permite a los usuarios arrastrar hacia abajo al comienzo del contenido de una app para actualizar los datos.
Plataforma de la API
Usa el elemento componible PullToRefreshBox
para implementar la función de deslizar para actualizar, que actúa como contenedor de tu contenido desplazable. Los siguientes parámetros clave controlan el comportamiento y la apariencia de la actualización:
isRefreshing
: Un valor booleano que indica si la acción de actualización está en curso.onRefresh
: Es una función lambda que se ejecuta cuando el usuario inicia una actualización.indicator
: Personaliza el indicador que se dibuja en la acción de deslizar para actualizar.
Ejemplo básico
En este fragmento, se muestra el 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) }) } } } }
Puntos clave sobre el código
PullToRefreshBox
une unLazyColumn
, que muestra una lista de cadenas.PullToRefreshBox
requiere los parámetrosisRefreshing
yonRefresh
.- El contenido dentro del bloque
PullToRefreshBox
representa el contenido desplazable.
Resultado
En este video, se muestra la implementación básica de la función de deslizar para actualizar del código anterior:
Ejemplo avanzado: Cómo personalizar el color del 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) }) } } } }
Puntos clave sobre el código
- El color del indicador se personaliza a través de las propiedades
containerColor
ycolor
en el parámetroindicator
. rememberPullToRefreshState()
administra el estado de la acción de actualización. Usas este estado junto con el parámetroindicator
.
Resultado
En este video, se muestra una implementación de la función de deslizar para actualizar con un indicador de color:
Ejemplo avanzado: Crea un indicador totalmente personalizado
Puedes crear indicadores personalizados complejos aprovechando los elementos componibles y las animaciones existentes.En este fragmento, se muestra cómo crear un indicador totalmente personalizado en tu implementación de la función de deslizar para actualizar:
@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 } ) } } } }
Puntos clave sobre el código
- En el fragmento anterior, se usó el
Indicator
que proporciona la biblioteca. Este fragmento crea un elemento componible de indicador personalizado llamadoMyCustomIndicator
. En este elemento componible, el modificadorpullToRefreshIndicator
controla el posicionamiento y activa una actualización. - Al igual que en el fragmento anterior, se extrajo la instancia de
PullToRefreshState
, por lo que se puede pasar la misma instancia aPullToRefreshBox
ypullToRefreshModifier
. - El color del contenedor y el umbral de posición se usan desde la clase
PullToRefreshDefaults
. De esta manera, puedes volver a usar el comportamiento y el diseño predeterminados de la biblioteca de Material, mientras personalizas solo los elementos que te interesan. MyCustomIndicator
usaCrossfade
para realizar la transición entre un ícono de nube y unCircularProgressIndicator
. El ícono de nube se amplía a medida que el usuario tira y cambia aCircularProgressIndicator
cuando comienza la acción de actualización.targetState
usaisRefreshing
para determinar qué estado mostrar (el ícono de nube o el indicador de progreso circular).animationSpec
define una animacióntween
para la transición, con una duración especificada deCROSSFADE_DURATION_MILLIS
.state.distanceFraction
representa la cantidad de veces que el usuario bajó el elemento, que varía de0f
(sin bajar) a1f
(completamente bajado).- El modificador
graphicsLayer
modifica la escala y la transparencia.
Resultado
En este video, se muestra el indicador personalizado del código anterior: