androidandroid-jetpack-composeandroid-jetpack-compose-material3

How to use swipe (pull) to refresh with Material 3?


val pullRefreshState = rememberPullRefreshState(loadStatus is LoadState.Loading, onRefresh = {
    photosResponse.refresh()
})
Box(
    modifier
        .fillMaxSize()
        .pullRefresh(pullRefreshState)

enter image description here

I have updated Material 2 to Material 3:

api(libs.androidx.compose.material3) // group = "androidx.compose.material3", name = "material3"

But now I can't use swipe to refresh, there is nothing to import


Solution

  • UPDATE

    With new release of M3, there is Pull to refresh Box widget that works great. Here is an example from official docs

    @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) })
                }
            }
        }
    }
    

    Old Answer

    Official version of Pull-to-refresh have been released for beta testing. Make sure you have Material3 1.2.0-beta01 or higher.

    implementation("androidx.compose.material3:material3:1.2.0-beta01")

    then check out example here. I will paste example for future reference if things changes in Android documentation:

    import androidx.compose.foundation.layout.Box
    import androidx.compose.foundation.layout.fillMaxSize
    import androidx.compose.foundation.lazy.LazyColumn
    import androidx.compose.material3.ListItem
    import androidx.compose.material3.Text
    import androidx.compose.material3.pulltorefresh.PullToRefreshContainer
    import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
    import androidx.compose.runtime.LaunchedEffect
    import androidx.compose.runtime.mutableStateOf
    import androidx.compose.runtime.remember
    import androidx.compose.ui.input.nestedscroll.nestedScroll
    
    var itemCount by remember { mutableStateOf(15) }
    val state = rememberPullToRefreshState()
    if (state.isRefreshing) {
        LaunchedEffect(true) {
            // fetch something
            delay(1500)
            itemCount += 5
            state.endRefresh()
        }
    }
    Box(Modifier.nestedScroll(state.nestedScrollConnection)) {
        LazyColumn(Modifier.fillMaxSize()) {
            if (!state.isRefreshing) {
                items(itemCount) {
                    ListItem({ Text(text = "Item ${itemCount - it}") })
                }
            }
        }
        PullToRefreshContainer(
            modifier = Modifier.align(Alignment.TopCenter),
            state = state,
        )
    }
    

    Hope this help!