# LazyListState

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/lazy/LazyListState.kt+class:androidx.compose.foundation.lazy.LazyListState) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.0.0) Common/All
- Cmn

  ```
  class LazyListState : ScrollableState
  ```

*** ** * ** ***

A state object that can be hoisted to control and observe scrolling.

In most cases, this will be created via `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/rememberLazyListState.composable#rememberLazyListState(kotlin.Int,kotlin.Int)`.

## Summary

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

| ### Public constructors |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#LazyListState(kotlin.Int,kotlin.Int)( firstVisibleItemIndex: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html, firstVisibleItemScrollOffset: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html )` | Cmn |
| `@https://developer.android.com/reference/kotlin/androidx/compose/foundation/ExperimentalFoundationApi [LazyListState](https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#LazyListState(androidx.compose.foundation.lazy.layout.LazyLayoutCacheWindow,kotlin.Int,kotlin.Int))( cacheWindow: https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutCacheWindow, firstVisibleItemIndex: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html, firstVisibleItemScrollOffset: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html )` **This function is deprecated.** \`CacheWindow\` is now specified via lazy list composable arguments as \`CacheWindow\`. | Cmn |
| `@https://developer.android.com/reference/kotlin/androidx/compose/foundation/ExperimentalFoundationApi [LazyListState](https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#LazyListState(kotlin.Int,kotlin.Int,androidx.compose.foundation.lazy.LazyListPrefetchStrategy))( firstVisibleItemIndex: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html, firstVisibleItemScrollOffset: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html, prefetchStrategy: https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListPrefetchStrategy )` **This function is deprecated.** \`LazyListPrefetchStrategy\` is deprecated. | Cmn |

| ### Public functions |
|---|---|---|
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#animateScrollToItem(kotlin.Int,kotlin.Int)(index: @https://developer.android.com/reference/kotlin/androidx/annotation/IntRange(from = 0) https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html, scrollOffset: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html)` Animate (smooth scroll) to the given item. | Cmn |
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#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 |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#requestScrollToItem(kotlin.Int,kotlin.Int)(index: @https://developer.android.com/reference/kotlin/androidx/annotation/IntRange(from = 0) https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html, scrollOffset: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html)` Requests the item at `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#requestScrollToItem(kotlin.Int,kotlin.Int)` to be at the start of the viewport during the next remeasure, offset by `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#requestScrollToItem(kotlin.Int,kotlin.Int)`, and schedules a remeasure. | Cmn |
| `open suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#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/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#scrollToItem(kotlin.Int,kotlin.Int)(index: @https://developer.android.com/reference/kotlin/androidx/annotation/IntRange(from = 0) https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html, scrollOffset: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html)` Instantly brings the item at `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#scrollToItem(kotlin.Int,kotlin.Int)` to the top of the viewport, offset by `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#scrollToItem(kotlin.Int,kotlin.Int)` 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/lazy/LazyListState#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/lazy/LazyListState#canScrollForward()` Whether this `https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/ScrollableState` can scroll forward (consume a positive delta). | Cmn |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#firstVisibleItemIndex()` The index of the first item that is visible within the scrollable viewport area not including items in the content padding region. | Cmn |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#firstVisibleItemScrollOffset()` The scroll offset of the first visible item. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/interaction/InteractionSource` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#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/lazy/LazyListState#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/lazy/LazyListState#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/lazy/LazyListState#lastScrolledForward()` The value of this property is true under the following scenarios, otherwise it's false. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListLayoutInfo` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#layoutInfo()` The object of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListLayoutInfo` calculated during the last layout pass. | Cmn |
| `open https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollIndicatorState?` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#scrollIndicatorState()` `https://developer.android.com/reference/kotlin/androidx/compose/foundation/ScrollIndicatorState` used for drawing a scroll indicator (e.g., a scrollbar). | 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<LazyListState, *>
```

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

## Public constructors

### LazyListState

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

```
LazyListState(
    firstVisibleItemIndex: Int = 0,
    firstVisibleItemScrollOffset: Int = 0
)
```

| Parameters |
|---|---|
| `firstVisibleItemIndex: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html = 0` | the initial value for `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#firstVisibleItemIndex()` |
| `firstVisibleItemScrollOffset: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html = 0` | the initial value for `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#firstVisibleItemScrollOffset()` |

### LazyListState

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

```
@ExperimentalFoundationApi
[LazyListState](https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#LazyListState(androidx.compose.foundation.lazy.layout.LazyLayoutCacheWindow,kotlin.Int,kotlin.Int))(
    cacheWindow: LazyLayoutCacheWindow,
    firstVisibleItemIndex: Int = 0,
    firstVisibleItemScrollOffset: Int = 0
)
```

> [!CAUTION]
> **This function is deprecated.**   
> \`CacheWindow\` is now specified via lazy list composable arguments as \`CacheWindow\`.

| Parameters |
|---|---|
| `cacheWindow: https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutCacheWindow` | specifies the size of the ahead and behind window to be used as per `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutCacheWindow`. |
| `firstVisibleItemIndex: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html = 0` | the initial value for `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#firstVisibleItemIndex()` |
| `firstVisibleItemScrollOffset: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html = 0` | the initial value for `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#firstVisibleItemScrollOffset()` |

### LazyListState

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

```
@ExperimentalFoundationApi
[LazyListState](https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#LazyListState(kotlin.Int,kotlin.Int,androidx.compose.foundation.lazy.LazyListPrefetchStrategy))(
    firstVisibleItemIndex: Int = 0,
    firstVisibleItemScrollOffset: Int = 0,
    prefetchStrategy: LazyListPrefetchStrategy = LazyListPrefetchStrategy()
)
```

> [!CAUTION]
> **This function is deprecated.**   
> \`LazyListPrefetchStrategy\` is deprecated. Prefetching behaviour should be specified via lazy list composable arguments as a \`CacheWindow\`.

A state object that can be hoisted to control and observe scrolling.

In most cases, this will be created via `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/rememberLazyListState.composable#rememberLazyListState(kotlin.Int,kotlin.Int)`.

| Parameters |
|---|---|
| `firstVisibleItemIndex: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html = 0` | the initial value for `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#firstVisibleItemIndex()` |
| `firstVisibleItemScrollOffset: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html = 0` | the initial value for `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#firstVisibleItemScrollOffset()` |
| `prefetchStrategy: https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListPrefetchStrategy = LazyListPrefetchStrategy()` | the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListPrefetchStrategy` to use for prefetching content in this list |

## Public functions

### animateScrollToItem

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

```
suspend fun animateScrollToItem(index: @IntRange(from = 0) Int, scrollOffset: Int = 0): Unit
```

Animate (smooth scroll) to the given item.

| Parameters |
|---|---|
| `index: @https://developer.android.com/reference/kotlin/androidx/annotation/IntRange(from = 0) https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html` | the index to which to scroll. Must be non-negative. |
| `scrollOffset: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html = 0` | the offset that the item should end up after the scroll. Note that positive offset refers to forward scroll, so in a top-to-bottom list, positive offset will scroll the item further upward (taking it partly offscreen). |

### 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 |

### requestScrollToItem

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

```
fun requestScrollToItem(index: @IntRange(from = 0) Int, scrollOffset: Int = 0): Unit
```

Requests the item at `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#requestScrollToItem(kotlin.Int,kotlin.Int)` to be at the start of the viewport during the next remeasure, offset by `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#requestScrollToItem(kotlin.Int,kotlin.Int)`, and schedules a remeasure.

The scroll position will be updated to the requested position rather than maintain the index based on the first visible item key (when a data set change will also be applied during the next remeasure), but *only* for the next remeasure.

Any scroll in progress will be cancelled.

| Parameters |
|---|---|
| `index: @https://developer.android.com/reference/kotlin/androidx/annotation/IntRange(from = 0) https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html` | the index to which to scroll. Must be non-negative. |
| `scrollOffset: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html = 0` | the offset that the item should end up after the scroll. Note that positive offset refers to forward scroll, so in a top-to-bottom list, positive offset will scroll the item further upward (taking it partly offscreen). |

### 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/lazy/LazyListState#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/lazy/LazyListState#scroll(androidx.compose.foundation.MutatePriority,kotlin.coroutines.SuspendFunction1)` is called from elsewhere, this will be canceled.

### scrollToItem

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

```
suspend fun scrollToItem(index: @IntRange(from = 0) Int, scrollOffset: Int = 0): Unit
```

Instantly brings the item at `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#scrollToItem(kotlin.Int,kotlin.Int)` to the top of the viewport, offset by `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#scrollToItem(kotlin.Int,kotlin.Int)` pixels.

| Parameters |
|---|---|
| `index: @https://developer.android.com/reference/kotlin/androidx/annotation/IntRange(from = 0) https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html` | the index to which to scroll. Must be non-negative. |
| `scrollOffset: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html = 0` | the offset that the item should end up after the scroll. Note that positive offset refers to forward scroll, so in a top-to-bottom list, positive offset will scroll the item further upward (taking it partly offscreen). |

## 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,
    )
}
```

### firstVisibleItemIndex

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

```
val firstVisibleItemIndex: Int
```

The index of the first item that is visible within the scrollable viewport area not including items in the content padding region. For the first visible item that includes items in the content padding please use `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListLayoutInfo#visibleItemsInfo()`.

Note that this property is observable and if you use it in the composable function it will be recomposed on every change causing potential performance issues.

If you want to run some side effects like sending an analytics event or updating a state based on this value consider using "snapshotFlow":

```kotlin
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
import androidx.compose.runtime.remember
import androidx.compose.runtime.snapshotFlow

val listState = rememberLazyListState()
LaunchedEffect(listState) {
    snapshotFlow { listState.firstVisibleItemIndex }
        .collect {
            // use the new index
        }
}
```

If you need to use it in the composition then consider wrapping the calculation into a derived state in order to only have recompositions when the derived value changes:

```kotlin
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.Button
import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.remember

val listState = rememberLazyListState()
val isAtTop by remember {
    derivedStateOf {
        listState.firstVisibleItemIndex == 0 && listState.firstVisibleItemScrollOffset == 0
    }
}
if (!isAtTop) {
    ScrollToTopButton(listState)
}
```

### firstVisibleItemScrollOffset

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

```
val firstVisibleItemScrollOffset: Int
```

The scroll offset of the first visible item. Scrolling forward is positive - i.e., the amount that the item is offset backwards.

Note that this property is observable and if you use it in the composable function it will be recomposed on every scroll causing potential performance issues.

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#firstVisibleItemIndex()` | for samples with the recommended usage patterns. |

### 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 animated scroll) is in progress, use `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState#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.

### layoutInfo

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

```
val layoutInfo: LazyListLayoutInfo
```

The object of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListLayoutInfo` calculated during the last layout pass. For example, you can use it to calculate what items are currently visible.

Note that this property is observable and is updated after every scroll or remeasure. If you use it in the composable function it will be recomposed on every change causing potential performance issues including infinity recomposition loop. Therefore, avoid using it in the composition.

If you want to run some side effects like sending an analytics event or updating a state based on this value consider using "snapshotFlow":

```kotlin
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
import androidx.compose.runtime.remember
import androidx.compose.runtime.snapshotFlow

val listState = rememberLazyListState()
LaunchedEffect(listState) {
    snapshotFlow { listState.layoutInfo.totalItemsCount }
        .collect {
            // use the new items count
        }
}
```

### 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.