# ScrollState

Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/Scroll.kt+class:androidx.compose.foundation.ScrollState) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0) Common/AllAndroid/JVM
- Cmn

  ```
  class ScrollState : ScrollableState
  ```

*** ** * ** ***

State of the scroll. Allows the developer to change the scroll position or get current state by calling methods on this object. To be hosted and passed to `https://developer.android.com/reference/kotlin/androidx/compose/foundation/verticalScroll.modifier#(androidx.compose.ui.Modifier).verticalScroll(androidx.compose.foundation.ScrollState,kotlin.Boolean,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean)` or `https://developer.android.com/reference/kotlin/androidx/compose/foundation/horizontalScroll.modifier#(androidx.compose.ui.Modifier).horizontalScroll(androidx.compose.foundation.ScrollState,kotlin.Boolean,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean)`

To create and automatically remember `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState` with default parameters use `https://developer.android.com/reference/kotlin/androidx/compose/foundation/rememberScrollState.composable#rememberScrollState(kotlin.Int)`.

Learn how to control the state of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/verticalScroll.modifier#(androidx.compose.ui.Modifier).verticalScroll(androidx.compose.foundation.ScrollState,kotlin.Boolean,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean)` or `https://developer.android.com/reference/kotlin/androidx/compose/foundation/horizontalScroll.modifier#(androidx.compose.ui.Modifier).horizontalScroll(androidx.compose.foundation.ScrollState,kotlin.Boolean,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean)`:

```kotlin
import androidx.compose.foundation.gestures.animateScrollBy
import androidx.compose.foundation.gestures.scrollBy
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.rememberScrollState
import androidx.compose.material3.Text
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier

// Create ScrollState to own it and be able to control scroll behaviour of scrollable Row below
val scrollState = rememberScrollState()
val scope = rememberCoroutineScope()
Column {
    Row(Modifier.horizontalScroll(scrollState)) { repeat(1000) { index -> Square(index) } }
    // Controls for scrolling
    Row(verticalAlignment = Alignment.CenterVertically) {
        Text("Scroll")
        Button(onClick = { scope.launch { scrollState.scrollTo(scrollState.value - 1000) } }) {
            Text("< -")
        }
        Button(onClick = { scope.launch { scrollState.scrollBy(10000f) } }) { Text("--- >") }
    }
    Row(verticalAlignment = Alignment.CenterVertically) {
        Text("Smooth Scroll")
        Button(
            onClick = { scope.launch { scrollState.animateScrollTo(scrollState.value - 1000) } }
        ) {
            Text("< -")
        }
        Button(onClick = { scope.launch { scrollState.animateScrollBy(10000f) } }) {
            Text("--- >")
        }
    }
}
```

## Summary

| ### Public companion properties |
|---|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/runtime/saveable/Saver<https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState, *>` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState#Saver()` The default `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState#Saver()` implementation for `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState`. | Cmn |

| ### Public constructors |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState#ScrollState(kotlin.Int)(initial: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html)` | Cmn |

| ### Public functions |
|---|---|---|
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState#animateScrollTo(kotlin.Int,androidx.compose.animation.core.AnimationSpec)(value: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html, animationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html>)` Scroll to position in pixels with animation. | Cmn |
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState#dispatchRawDelta(kotlin.Float)(delta: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html)` Dispatch scroll delta in pixels avoiding all scroll related mechanisms. | Cmn |
| `open suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState#scroll(androidx.compose.foundation.MutatePriority,kotlin.coroutines.SuspendFunction1)(scrollPriority: https://developer.android.com/reference/kotlin/androidx/compose/foundation/MutatePriority, block: suspend https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollScope.() -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html)` Call this function to take control of scrolling and gain the ability to send scroll events via `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollScope#scrollBy(kotlin.Float)`. | Cmn |
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState#scrollTo(kotlin.Int)(value: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html)` Instantly jump to the given position in pixels. | Cmn |

| ### Public properties |
|---|---|---|
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState#canScrollBackward()` Whether this `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState` can scroll backward (consume a negative delta). | Cmn |
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState#canScrollForward()` Whether this `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState` can scroll forward (consume a positive delta). | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/interaction/InteractionSource` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState#interactionSource()` `https://developer.android.com/reference/kotlin/androidx/compose/foundation/interaction/InteractionSource` that will be used to dispatch drag events when this list is being dragged. | Cmn |
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState#isScrollInProgress()` Whether this `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState` is currently scrolling by gesture, fling or programmatically or not. | Cmn |
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState#lastScrolledBackward()` The value of this property is true under the following scenarios, otherwise it's false. | Cmn |
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState#lastScrolledForward()` The value of this property is true under the following scenarios, otherwise it's false. | Cmn |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState#maxValue()` maximum bound for `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState#value()`, or `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/-companion/-m-a-x_-v-a-l-u-e.html` if still unknown | Cmn |
| `open https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollIndicatorState?` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState#scrollIndicatorState()` `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollIndicatorState` used for drawing a scroll indicator (e.g., a scrollbar). | Cmn |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState#value()` current scroll position value in pixels | Cmn |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState#viewportSize()` Size of the viewport on the scrollable axis, or 0 if still unknown. | Cmn |

## Public companion properties

### Saver

Cmn Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0)

```
val Saver: Saver<ScrollState, *>
```

The default `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState#Saver()` implementation for `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState`.

## Public constructors

### ScrollState

Cmn Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0)

```
ScrollState(initial: Int)
```

| Parameters |
|---|---|
| `initial: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html` | value of the scroll |

## Public functions

### animateScrollTo

Cmn Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0)

```
suspend fun animateScrollTo(
    value: Int,
    animationSpec: AnimationSpec<Float> = SpringSpec()
): Unit
```

Scroll to position in pixels with animation.

| Parameters |
|---|---|
| `value: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html` | target value in pixels to smooth scroll to, value will be coerced to 0..maxPosition |
| `animationSpec: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/AnimationSpec<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html> = SpringSpec()` | animation curve for smooth scroll animation |

### dispatchRawDelta

Cmn

```
open fun dispatchRawDelta(delta: Float): Float
```

Dispatch scroll delta in pixels avoiding all scroll related mechanisms.

**NOTE:** unlike `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState#scroll(androidx.compose.foundation.MutatePriority,kotlin.coroutines.SuspendFunction1)`, dispatching any delta with this method won't trigger nested scroll, won't stop ongoing scroll/drag animation and will bypass scrolling of any priority. This method will also ignore `reverseDirection` and other parameters set in scrollable.

This method is used internally for nested scrolling dispatch and other low level operations, allowing implementers of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState` influence the consumption as suits them. Manually dispatching delta via this method will likely result in a bad user experience, you must prefer `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState#scroll(androidx.compose.foundation.MutatePriority,kotlin.coroutines.SuspendFunction1)` method over this one.

| Parameters |
|---|---|
| `delta: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | amount of scroll dispatched in the nested scroll process |

| Returns |
|---|---|
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | the amount of delta consumed |

### scroll

Cmn

```
open suspend fun scroll(
    scrollPriority: MutatePriority = MutatePriority.Default,
    block: suspend ScrollScope.() -> Unit
): Unit
```

Call this function to take control of scrolling and gain the ability to send scroll events via `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollScope#scrollBy(kotlin.Float)`. All actions that change the logical scroll position must be performed within a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState#scroll(androidx.compose.foundation.MutatePriority,kotlin.coroutines.SuspendFunction1)` block (even if they don't call any other methods on this object) in order to guarantee that mutual exclusion is enforced.

If `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState#scroll(androidx.compose.foundation.MutatePriority,kotlin.coroutines.SuspendFunction1)` is called from elsewhere with the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState#scroll(androidx.compose.foundation.MutatePriority,kotlin.coroutines.SuspendFunction1)` higher or equal to ongoing scroll, ongoing scroll will be canceled.

### scrollTo

Cmn

```
suspend fun scrollTo(value: Int): Float
```

Instantly jump to the given position in pixels.

Cancels the currently running scroll, if any, and suspends until the cancellation is complete.

| Parameters |
|---|---|
| `value: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html` | number of pixels to scroll by |

| Returns |
|---|---|
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | the amount of scroll consumed |

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState#animateScrollTo(kotlin.Int,androidx.compose.animation.core.AnimationSpec)` | for an animated version |

## Public properties

### canScrollBackward

Cmn

```
open val canScrollBackward: Boolean
```

Whether this `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState` can scroll backward (consume a negative delta). This is typically false if the scroll position is equal to its minimum value, and true otherwise.

Note that `true` here does not imply that delta *will* be consumed - the ScrollableState may decide not to handle the incoming delta (such as if it is already being scrolled separately). Additionally, for backwards compatibility with previous versions of ScrollableState this value defaults to `true`.

```kotlin
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.KeyboardArrowDown
import androidx.compose.material.icons.filled.KeyboardArrowUp
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer

val state = rememberLazyListState()
Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
    Icon(
        Icons.Filled.KeyboardArrowUp,
        null,
        Modifier.graphicsLayer {
            // Hide the icon if we cannot scroll backward (we are the start of the list)
            // We use graphicsLayer here to control the alpha so that we only redraw when this
            // value changes, instead of recomposing
            alpha = if (state.canScrollBackward) 1f else 0f
        },
        Color.Red,
    )
    val items = (1..100).toList()
    LazyColumn(Modifier.weight(1f).fillMaxWidth(), state) {
        items(items) { Text("Item is $it") }
    }
    Icon(
        Icons.Filled.KeyboardArrowDown,
        null,
        Modifier.graphicsLayer {
            // Hide the icon if we cannot scroll forward (we are the end of the list)
            // We use graphicsLayer here to control the alpha so that we only redraw when this
            // value changes, instead of recomposing
            alpha = if (state.canScrollForward) 1f else 0f
        },
        Color.Red,
    )
}
```

### canScrollForward

Cmn

```
open val canScrollForward: Boolean
```

Whether this `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState` can scroll forward (consume a positive delta). This is typically false if the scroll position is equal to its maximum value, and true otherwise.

Note that `true` here does not imply that delta *will* be consumed - the ScrollableState may decide not to handle the incoming delta (such as if it is already being scrolled separately). Additionally, for backwards compatibility with previous versions of ScrollableState this value defaults to `true`.

```kotlin
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.KeyboardArrowDown
import androidx.compose.material.icons.filled.KeyboardArrowUp
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer

val state = rememberLazyListState()
Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
    Icon(
        Icons.Filled.KeyboardArrowUp,
        null,
        Modifier.graphicsLayer {
            // Hide the icon if we cannot scroll backward (we are the start of the list)
            // We use graphicsLayer here to control the alpha so that we only redraw when this
            // value changes, instead of recomposing
            alpha = if (state.canScrollBackward) 1f else 0f
        },
        Color.Red,
    )
    val items = (1..100).toList()
    LazyColumn(Modifier.weight(1f).fillMaxWidth(), state) {
        items(items) { Text("Item is $it") }
    }
    Icon(
        Icons.Filled.KeyboardArrowDown,
        null,
        Modifier.graphicsLayer {
            // Hide the icon if we cannot scroll forward (we are the end of the list)
            // We use graphicsLayer here to control the alpha so that we only redraw when this
            // value changes, instead of recomposing
            alpha = if (state.canScrollForward) 1f else 0f
        },
        Color.Red,
    )
}
```

### interactionSource

Cmn Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0)

```
val interactionSource: InteractionSource
```

`https://developer.android.com/reference/kotlin/androidx/compose/foundation/interaction/InteractionSource` that will be used to dispatch drag events when this list is being dragged. If you want to know whether the fling (or smooth scroll) is in progress, use `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState#isScrollInProgress()`.

### isScrollInProgress

Cmn

```
open val isScrollInProgress: Boolean
```

Whether this `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState` is currently scrolling by gesture, fling or programmatically or not.

### lastScrolledBackward

Cmn

```
open val lastScrolledBackward: Boolean
```

The value of this property is true under the following scenarios, otherwise it's false.

- This `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState` is currently scrolling backward.

- This `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState` was scrolling backward in its last scroll action.

### lastScrolledForward

Cmn

```
open val lastScrolledForward: Boolean
```

The value of this property is true under the following scenarios, otherwise it's false.

- This `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState` is currently scrolling forward.

- This `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState` was scrolling forward in its last scroll action.

### maxValue

Cmn Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0)

```
val maxValue: Int
```

maximum bound for `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollState#value()`, or `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/-companion/-m-a-x_-v-a-l-u-e.html` if still unknown

### scrollIndicatorState

Cmn

```
open val scrollIndicatorState: ScrollIndicatorState?
```

`https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollIndicatorState` used for drawing a scroll indicator (e.g., a scrollbar).

This property may be `null` if scroll indicators are not applicable or if the underlying scrollable component does not support or provide this state.

### value

Cmn Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0)

```
val value: Int
```

current scroll position value in pixels

### viewportSize

Cmn Added in [1.6.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.6.0)

```
val viewportSize: Int
```

Size of the viewport on the scrollable axis, or 0 if still unknown. Note that this value is only populated after the first measure pass.