---
title: "PullToRefreshState"
description: "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:"
type: "interface"
---

<div class='type'>Interface</div>


<a id='references'></a>

<div class='sourceset sourceset-common'>Common</div>



```kotlin
interface 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:


## Properties

<div class='sourceset sourceset-common'>Common</div>


```kotlin
@get:FloatRange(from = 0.0) val distanceFraction: Float
```


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.



<div class='sourceset sourceset-common'>Common</div>


```kotlin
val isAnimating: Boolean
```


whether the state is currently animating the indicator to the threshold offset, or back to
the hidden offset



## Functions

```kotlin
suspend fun animateToThreshold()
```


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


```kotlin
suspend fun animateToHidden()
```


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


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


Snap the indicator to the desired threshold fraction



## Code Examples

### PullToRefreshLinearProgressIndicatorSample
```kotlin
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@Preview
fun PullToRefreshLinearProgressIndicatorSample() {
    var itemCount by remember { mutableIntStateOf(15) }
    var isRefreshing by remember { mutableStateOf(false) }
    val state = rememberPullToRefreshState()
    val coroutineScope = rememberCoroutineScope()
    val onRefresh: () -> Unit = {
        isRefreshing = true
        coroutineScope.launch {
            // fetch something
            delay(5000)
            itemCount += 5
            isRefreshing = false
        }
    }
    Scaffold(
        modifier =
            Modifier.pullToRefresh(
                state = state,
                isRefreshing = isRefreshing,
                onRefresh = onRefresh,
            ),
        topBar = {
            TopAppBar(
                title = { Text("TopAppBar") },
                // Provide an accessible alternative to trigger refresh.
                actions = {
                    IconButton(onClick = onRefresh) {
                        Icon(Icons.Filled.Refresh, "Trigger Refresh")
                    }
                },
            )
        },
    ) {
        Box(Modifier.padding(it)) {
            LazyColumn(Modifier.fillMaxSize()) {
                if (!isRefreshing) {
                    items(itemCount) { ListItem({ Text(text = "Item ${itemCount - it}") }) }
                }
            }
            if (isRefreshing) {
                LinearProgressIndicator(modifier = Modifier.fillMaxWidth())
            } else {
                LinearProgressIndicator(
                    modifier = Modifier.fillMaxWidth(),
                    progress = { state.distanceFraction },
                )
            }
        }
    }
}
```

