bryankeltonadams
03/11/2024, 5:19 PMbryankeltonadams
03/11/2024, 5:19 PMval rememberPullToRefreshState = rememberPullToRefreshState(enabled = {
true
})
if (rememberPullToRefreshState.isRefreshing) {
LaunchedEffect(true) {
// fetch something
refresh()
}
}
//from viewModel, set to true when refresh is called, and set to false at the end of refresh on error or success
if (!isRefreshing) {
LaunchedEffect(true) {
if(rememberPullToRefreshState.isRefreshing) {
rememberPullToRefreshState.endRefresh()
}
}
}
bryankeltonadams
03/11/2024, 5:22 PMimport androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.ListItem
import androidx.compose.material.Text
import androidx.compose.material.pullrefresh.PullRefreshIndicator
import androidx.compose.material.pullrefresh.pullRefresh
import androidx.compose.material.pullrefresh.rememberPullRefreshState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
val refreshScope = rememberCoroutineScope()
var refreshing by remember { mutableStateOf(false) }
var itemCount by remember { mutableStateOf(15) }
fun refresh() = refreshScope.launch {
refreshing = true
delay(1500)
itemCount += 5
refreshing = false
}
val state = rememberPullRefreshState(refreshing, ::refresh)
Box(Modifier.pullRefresh(state)) {
LazyColumn(Modifier.fillMaxSize()) {
if (!refreshing) {
items(itemCount) {
ListItem { Text(text = "Item ${itemCount - it}") }
}
}
}
PullRefreshIndicator(refreshing, state, Modifier.align(Alignment.TopCenter))
}
bryankeltonadams
03/11/2024, 5:45 PMsindrenm
03/11/2024, 9:38 PMPullToRefreshState
in my view model, but that's also not easy because of the required positionalThreshold: Float
that it needs to build it. 🤔Stylianos Gakis
03/11/2024, 9:48 PMbryankeltonadams
03/11/2024, 9:57 PMbryankeltonadams
03/12/2024, 10:33 PMsindrenm
03/13/2024, 2:31 PMStylianos Gakis
03/13/2024, 2:34 PMAndré Kindwall
04/16/2024, 10:54 AMStylianos Gakis
04/16/2024, 10:58 AM@Preview
@Sampled
fun PullToRefreshViewModelSample() {
val viewModel = remember {
object : ViewModel() {
private val refreshRequests = Channel<Unit>(1)
var isRefreshing by mutableStateOf(false)
private set
var itemCount by mutableStateOf(15)
private set
init {
viewModelScope.launch {
for (r in refreshRequests) {
isRefreshing = true
try {
itemCount += 5
delay(1000) // simulate doing real work
} finally {
isRefreshing = false
}
}
}
}
fun refresh() {
refreshRequests.trySend(Unit)
}
}
}
Scaffold(
topBar = {
TopAppBar(
title = { Text("Title") },
// Provide an accessible alternative to trigger refresh.
actions = {
IconButton(
enabled = !viewModel.isRefreshing,
onClick = { viewModel.refresh() }) {
Icon(Icons.Filled.Refresh, "Trigger Refresh")
}
}
)
}
) {
PullToRefreshBox(
modifier = Modifier.padding(it),
isRefreshing = viewModel.isRefreshing,
onRefresh = { viewModel.refresh() }
) {
LazyColumn(Modifier.fillMaxSize()) {
if (!viewModel.isRefreshing) {
items(viewModel.itemCount) {
ListItem({ Text(text = "Item ${viewModel.itemCount - it}") })
}
}
}
}
}
}
With the VM holding the single source of truth for the refreshing state!bryankeltonadams
04/16/2024, 6:33 PM