Implement intuitive pull-to-refresh functionality in Compose using PullToRefreshBox. Combine it with Paging3 for seamless data loading.
Basic PullToRefreshBox Implementation
Use Material3's PullToRefreshBox for modern refresh UI:
var isRefreshing by remember { mutableStateOf(false) }
PullToRefreshBox(
isRefreshing = isRefreshing,
onRefresh = {
viewModel.refreshData()
isRefreshing = false
},
modifier = Modifier.fillMaxSize()
) {
LazyColumn {
items(items.size) { index ->
Text(items[index])
}
}
}
Managing Refresh State with ViewModel
Handle refresh logic asynchronously:
class ListViewModel(
private val repository: DataRepository
) : ViewModel() {
private val _isRefreshing = MutableStateFlow(false)
val isRefreshing = _isRefreshing.asStateFlow()
private val _items = MutableStateFlow<List<Item>>(emptyList())
val items = _items.asStateFlow()
fun refreshData() {
viewModelScope.launch {
_isRefreshing.value = true
try {
val newItems = repository.fetchLatest()
_items.value = newItems
} finally {
_isRefreshing.value = false
}
}
}
}
Paging3 Integration
Combine pull-to-refresh with infinite scrolling:
class PagingListViewModel(
private val repository: DataRepository
) : ViewModel() {
val pagingFlow = Pager(
config = PagingConfig(pageSize = 20),
pagingSourceFactory = { repository.pagingSource() }
).flow.cachedIn(viewModelScope)
}
// In Composable
val lazyPagingItems = pagingFlow.collectAsLazyPagingItems()
PullToRefreshBox(
isRefreshing = lazyPagingItems.loadState.refresh is LoadState.Loading,
onRefresh = { lazyPagingItems.refresh() }
) {
LazyColumn {
items(lazyPagingItems.itemCount) { index ->
lazyPagingItems[index]?.let { item ->
ItemRow(item)
}
}
}
}
Pull-to-refresh signals data freshness. Test edge cases like concurrent refresh and error handling.
8 Android app templates on Gumroad
Top comments (0)