Pull to refresh
Lets people reload a list by pulling it down, with a loading indicator as feedback.
- Category: Selection and input
- API status: Expressive
- Compose APIs:
PullToRefreshBox,PullToRefreshDefaults,rememberPullToRefreshState - Interactive page: https://m3e.ljzapps.app/#components/pull-to-refresh
When to use
Wrap a scrollable list in PullToRefreshBox and set isRefreshing while the reload runs. The default indicator is the Expressive loading indicator. Use the pointer to drag down or the touch gesture on supported devices.
Always offer another way to refresh, because not every input device can pull.
Examples
Refresh a list
Drag the list down with touch input, or scroll to the top and pull.
var refreshing by remember { mutableStateOf(false) }
var round by remember { mutableStateOf(1) }
val scope = rememberCoroutineScope()
PullToRefreshBox(
isRefreshing = refreshing,
onRefresh = {
scope.launch {
refreshing = true
delay(1_500)
round += 1
refreshing = false
}
},
modifier = Modifier.fillMaxWidth().height(320.dp),
) {
LazyColumn(Modifier.fillMaxWidth()) {
items((1..20).toList()) { index ->
ListItem(headlineContent = { Text("Item $index, load $round") })
}
}
}
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
isRefreshing | Boolean | Show the indicator while true. | |
onRefresh | () -> Unit | Called when the pull passes the threshold. | |
indicator | @Composable BoxScope.() -> Unit | default indicator | Replace to customise. |
state | PullToRefreshState | rememberPullToRefreshState() | Exposes the pull distance. |
Guidelines
Do:
- Refresh only content that can be stale.
- Keep the existing content visible while loading.
Don't:
- Do not use it on screens that are not scrollable.
- Do not trigger destructive actions.
Accessibility
- Provide a visible refresh button or menu item as an alternative to the gesture.
- Announce when new content has loaded.