Il componente Pull to refresh consente agli utenti di trascinare verso il basso all'inizio dei contenuti di un'app per aggiornare i dati.
Superficie API
Utilizza il componente componibile PullToRefreshBox
per implementare il trascinamento verso il basso per aggiornare, che
funge da contenitore per i contenuti scorrevoli. I seguenti parametri chiave
controllano il comportamento e l'aspetto dell'aggiornamento:
isRefreshing
: un valore booleano che indica se l'azione di aggiornamento è in corso.onRefresh
: una funzione Lambda che viene eseguita quando l'utente avvia un aggiornamento.indicator
: Personalizza l'indicatore che il sistema disegna quando si scorre verso il basso per aggiornare la pagina.
Esempio di base
Questo snippet mostra l'utilizzo di base di 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) }) } } } }
Punti chiave del codice
PullToRefreshBox
racchiude un elementoLazyColumn
, che mostra un elenco di stringhe.PullToRefreshBox
richiede i parametriisRefreshing
eonRefresh
.- I contenuti all'interno del blocco
PullToRefreshBox
rappresentano i contenuti scorrevoli.
Risultato
Questo video mostra l'implementazione di base del trascinamento per aggiornare dal codice precedente:
Esempio avanzato: personalizzare il colore dell'indicatore
@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) }) } } } }
Punti chiave del codice
- Il colore dell'indicatore viene personalizzato tramite le proprietà
containerColor
ecolor
nel parametroindicator
. rememberPullToRefreshState()
gestisce lo stato dell'azione di aggiornamento. Utilizzi questo stato insieme al parametroindicator
.
Risultato
Questo video mostra un'implementazione del trascinamento per aggiornare con un indicatore colorato:
Esempio avanzato: crea un indicatore completamente personalizzato
Puoi creare indicatori personalizzati complessi sfruttando i composable e le animazioni esistenti.Questo snippet mostra come creare un indicatore completamente personalizzato nell'implementazione del 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.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 } ) } } } }
Punti chiave del codice
- Lo snippet precedente utilizzava
Indicator
fornito dalla libreria. Questo snippet crea un composable indicatore personalizzato denominatoMyCustomIndicator
. In questo componibile, il modificatorepullToRefreshIndicator
gestisce il posizionamento e l'attivazione di un aggiornamento. - Come nello snippet precedente, l'esempio estrae l'istanza
PullToRefreshState
, in modo da poter passare la stessa istanza sia aPullToRefreshBox
sia apullToRefreshModifier
. - L'esempio utilizza il colore del contenitore e la soglia di posizione della classe
PullToRefreshDefaults
. In questo modo, puoi riutilizzare il comportamento e lo stile predefiniti della libreria Material, personalizzando solo gli elementi che ti interessano. MyCustomIndicator
utilizzaCrossfade
per passare da un'icona cloud a unCircularProgressIndicator
. L'icona del cloud aumenta di dimensioni quando l'utente tira e si trasforma in unCircularProgressIndicator
quando inizia l'azione di aggiornamento.targetState
utilizzaisRefreshing
per determinare lo stato da visualizzare (l'icona del cloud o l'indicatore di avanzamento circolare).animationSpec
definisce un'animazionetween
per la transizione, con una durata specificata diCROSSFADE_DURATION_MILLIS
.state.distanceFraction
rappresenta quanto l'utente ha tirato verso il basso, da0f
(nessun tiro) a1f
(tiro completo).- Il modificatore
graphicsLayer
modifica la scala e la trasparenza.
Risultato
Questo video mostra l'indicatore personalizzato del codice precedente: