Le composant "Pull to refresh" (Tirer pour actualiser) permet aux utilisateurs de faire glisser leur doigt vers le bas au début du contenu d'une application pour actualiser les données.
Surface d'API
Utilisez le PullToRefreshBox composable pour implémenter la fonctionnalité "Pull to refresh", qui
sert de conteneur pour votre contenu défilant. Les paramètres clés suivants contrôlent le comportement et l'apparence de l'actualisation :
isRefreshing: valeur booléenne indiquant si l'action d'actualisation est en cours.onRefresh: fonction lambda qui s'exécute lorsque l'utilisateur lance une actualisation.indicator: personnalise l'indicateur que le système dessine lors de l'actualisation.
Exemple de base
Cet extrait illustre l'utilisation de base 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) }) } } } }
Points clés concernant le code
PullToRefreshBoxencapsule unLazyColumn, qui affiche une liste de chaînes.PullToRefreshBoxnécessite les paramètresisRefreshingetonRefresh.- Le contenu du bloc
PullToRefreshBoxreprésente le contenu défilant.
Résultat
Cette vidéo illustre l'implémentation de base de la fonctionnalité "Pull to refresh" à partir du code précédent :
Exemple avancé : personnaliser la couleur de l'indicateur
@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) }) } } } }
Points clés concernant le code
- La couleur de l'indicateur est personnalisée via les propriétés
containerColoretcolordu paramètreindicator. rememberPullToRefreshState()gère l'état de l'action d'actualisation. Vous utilisez cet état conjointement avec le paramètreindicator.
Résultat
Cette vidéo montre une implémentation de la fonctionnalité "Pull to refresh" avec un indicateur coloré :
Exemple avancé : créer un indicateur entièrement personnalisé
Vous pouvez créer des indicateurs personnalisés complexes en tirant parti des composables et des animations existants.Cet extrait montre comment créer un indicateur entièrement personnalisé dans votre implémentation de la fonctionnalité "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 } ) } } } }
Points clés concernant le code
- L'extrait précédent utilisait l'
Indicatorfourni par la bibliothèque. Cet extrait crée un composable d'indicateur personnalisé appeléMyCustomIndicator. Dans ce composable, le modificateurpullToRefreshIndicatorgère le positionnement et le déclenchement d'une actualisation. - Comme dans l'extrait précédent, l'exemple extrait l'instance
PullToRefreshState. Vous pouvez ainsi transmettre la même instance à la fois àPullToRefreshBoxet àpullToRefreshModifier. - L'exemple utilise la couleur du conteneur et le seuil de position de la classe
PullToRefreshDefaults. Vous pouvez ainsi réutiliser le comportement et le style par défaut de la bibliothèque Material, tout en personnalisant uniquement les éléments qui vous intéressent. MyCustomIndicatorutiliseCrossfadepour effectuer une transition entre une icône de cloud et unCircularProgressIndicator. L'icône de cloud s'agrandit lorsque l'utilisateur tire, puis passe à unCircularProgressIndicatorlorsque l'action d'actualisation commence.targetStateutiliseisRefreshingpour déterminer l'état à afficher (l'icône de cloud ou l'indicateur de progression circulaire).animationSpecdéfinit une animationtweenpour la transition, avec une durée spécifiée deCROSSFADE_DURATION_MILLIS.state.distanceFractionreprésente la distance parcourue par l'utilisateur, allant de0f(aucun tirage) à1f(tirage complet).- Le modificateur
graphicsLayermodifie l'échelle et la transparence.
Résultat
Cette vidéo montre l'indicateur personnalisé du code précédent :