PullToRefreshState



The state of a PullToRefreshBox which tracks the distance that the container and indicator have been pulled.

Each instance of PullToRefreshBox should have its own PullToRefreshState.

PullToRefreshState can be used with other progress indicators like so:

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.ListItem
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.pulltorefresh.PullToRefreshState
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.Modifier
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()
    }
}
Scaffold(
    modifier = Modifier.nestedScroll(state.nestedScrollConnection),
    topBar = {
        TopAppBar(
            title = { Text("TopAppBar") },
            // Provide an accessible alternative to trigger refresh.
            actions = {
                IconButton(onClick = { state.startRefresh() }) {
                    Icon(Icons.Filled.Refresh, "Trigger Refresh")
                }
            }
        )
    }
) {
    Box(Modifier.padding(it)) {
        LazyColumn(Modifier.fillMaxSize()) {
            if (!state.isRefreshing) {
                items(itemCount) {
                    ListItem({ Text(text = "Item ${itemCount - it}") })
                }
            }
        }
        if (state.isRefreshing) {
            LinearProgressIndicator()
        } else {
            LinearProgressIndicator(progress = { state.progress })
        }
    }
}

Summary

Public functions

suspend Unit

Animate the distance towards the position where the indicator will be hidden when idle

Cmn
suspend Unit

Animate the distance towards the anchor or threshold position, where the indicator will be shown when refreshing.

Cmn
suspend Unit
snapTo(targetValue: @FloatRange(from = 0.0) Float)

Snap the indicator to the desired threshold fraction

Cmn

Public properties

Float

Distance percentage towards the refresh threshold.

Cmn
open Boolean

Whether the state is currently animating

Cmn

Public functions

animateToHidden

suspend fun animateToHidden(): Unit

Animate the distance towards the position where the indicator will be hidden when idle

animateToThreshold

suspend fun animateToThreshold(): Unit

Animate the distance towards the anchor or threshold position, where the indicator will be shown when refreshing.

snapTo

suspend fun snapTo(targetValue: @FloatRange(from = 0.0) Float): Unit

Snap the indicator to the desired threshold fraction

Public properties

distanceFraction

val distanceFractionFloat

Distance percentage towards the refresh threshold. 0.0 indicates no distance, 1.0 indicates being at the threshold offset, 1.0 indicates overshoot beyond the provided threshold.

isAnimating

open val isAnimatingBoolean

Whether the state is currently animating