androidx.compose.foundation.lazy

In this page, you'll find documentation for types, properties, and functions available in the androidx.compose.foundation.lazy package such as LazyColumn, LazyRow, and rememberLazyListState.

If you're looking for guidance instead, check out the Lists in Compose guide.

Interfaces

LazyItemScope

Receiver scope being used by the item content parameter of LazyColumn/Row.

Cmn
LazyListItemInfo

Contains useful information about an individual item in lazy lists like LazyColumn or LazyRow.

Cmn
LazyListLayoutInfo

Contains useful information about the currently displayed layout state of lazy lists like LazyColumn or LazyRow.

Cmn
LazyListPrefetchScope

Scope for callbacks in LazyListPrefetchStrategy which allows prefetches to be requested.

Cmn
LazyListPrefetchStrategy

Implementations of this interface control which indices of a LazyList should be prefetched (precomposed and premeasured during idle time) as the user interacts with it.

Cmn
LazyListScope

Receiver scope which is used by LazyColumn and LazyRow.

Cmn

Classes

LazyListState

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

Cmn

Annotations

LazyScopeMarker

DSL marker used to distinguish between lazy layout scope and the item scope.

Cmn

Top-level functions summary

Unit
@Composable
LazyColumn(
    modifier: Modifier,
    state: LazyListState,
    contentPadding: PaddingValues,
    reverseLayout: Boolean,
    verticalArrangement: Arrangement.Vertical,
    horizontalAlignment: Alignment.Horizontal,
    flingBehavior: FlingBehavior,
    userScrollEnabled: Boolean,
    overscrollEffect: OverscrollEffect?,
    content: LazyListScope.() -> Unit
)

The vertically scrolling list that only composes and lays out the currently visible items.

Cmn
LazyLayoutScrollScope

An implementation of LazyLayoutScrollScope that can be used with LazyLists.

Cmn
LazyListPrefetchStrategy

Creates an instance of the default LazyListPrefetchStrategy, allowing for customization of the nested prefetch count.

Cmn
Unit
@Composable
LazyRow(
    modifier: Modifier,
    state: LazyListState,
    contentPadding: PaddingValues,
    reverseLayout: Boolean,
    horizontalArrangement: Arrangement.Horizontal,
    verticalAlignment: Alignment.Vertical,
    flingBehavior: FlingBehavior,
    userScrollEnabled: Boolean,
    overscrollEffect: OverscrollEffect?,
    content: LazyListScope.() -> Unit
)

The horizontally scrolling list that only composes and lays out the currently visible items.

Cmn
LazyListState
@Composable
rememberLazyListState(
    initialFirstVisibleItemIndex: Int,
    initialFirstVisibleItemScrollOffset: Int
)

Creates a LazyListState that is remembered across compositions.

Cmn
LazyListState
@ExperimentalFoundationApi
@Composable
rememberLazyListState(
    initialFirstVisibleItemIndex: Int,
    initialFirstVisibleItemScrollOffset: Int,
    prefetchStrategy: LazyListPrefetchStrategy
)

Creates a LazyListState that is remembered across compositions.

Cmn

Extension functions summary

inline Unit
<T : Any?> LazyListScope.items(
    items: Array<T>,
    noinline key: ((item) -> Any)?,
    noinline contentType: (item) -> Any?,
    crossinline itemContent: @Composable LazyItemScope.(item) -> Unit
)

Adds an array of items.

Cmn
inline Unit
<T : Any?> LazyListScope.items(
    items: List<T>,
    noinline key: ((item) -> Any)?,
    noinline contentType: (item) -> Any?,
    crossinline itemContent: @Composable LazyItemScope.(item) -> Unit
)

Adds a list of items.

Cmn
inline Unit
<T : Any?> LazyListScope.itemsIndexed(
    items: Array<T>,
    noinline key: ((index: Int, item) -> Any)?,
    crossinline contentType: (index: Int, item) -> Any?,
    crossinline itemContent: @Composable LazyItemScope.(index: Int, item) -> Unit
)

Adds an array of items where the content of an item is aware of its index.

Cmn
inline Unit
<T : Any?> LazyListScope.itemsIndexed(
    items: List<T>,
    noinline key: ((index: Int, item) -> Any)?,
    crossinline contentType: (index: Int, item) -> Any?,
    crossinline itemContent: @Composable LazyItemScope.(index: Int, item) -> Unit
)

Adds a list of items where the content of an item is aware of its index.

Cmn

Top-level functions

@Composable
fun LazyColumn(
    modifier: Modifier = Modifier,
    state: LazyListState = rememberLazyListState(),
    contentPadding: PaddingValues = PaddingValues(0.dp),
    reverseLayout: Boolean = false,
    verticalArrangement: Arrangement.Vertical = if (!reverseLayout) Arrangement.Top else Arrangement.Bottom,
    horizontalAlignment: Alignment.Horizontal = Alignment.Start,
    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
    userScrollEnabled: Boolean = true,
    overscrollEffect: OverscrollEffect? = rememberOverscrollEffect(),
    content: LazyListScope.() -> Unit
): Unit

The vertically scrolling list that only composes and lays out the currently visible items. The content block defines a DSL which allows you to emit items of different types. For example you can use LazyListScope.item to add a single item and LazyListScope.items to add a list of items.

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material.Text

val itemsList = (0..5).toList()
val itemsIndexedList = listOf("A", "B", "C")

LazyColumn {
    items(itemsList) { Text("Item is $it") }

    item { Text("Single item") }

    itemsIndexed(itemsIndexedList) { index, item -> Text("Item at index $index is $item") }
}
Parameters
modifier: Modifier = Modifier

the modifier to apply to this layout.

state: LazyListState = rememberLazyListState()

the state object to be used to control or observe the list's state.

contentPadding: PaddingValues = PaddingValues(0.dp)

a padding around the whole content. This will add padding for the. content after it has been clipped, which is not possible via modifier param. You can use it to add a padding before the first item or after the last one. If you want to add a spacing between each item use verticalArrangement.

reverseLayout: Boolean = false

reverse the direction of scrolling and layout. When true, items are laid out in the reverse order and LazyListState.firstVisibleItemIndex == 0 means that column is scrolled to the bottom. Note that reverseLayout does not change the behavior of verticalArrangement, e.g. with Arrangement.Top (top) 123### (bottom) becomes (top) 321### (bottom).

verticalArrangement: Arrangement.Vertical = if (!reverseLayout) Arrangement.Top else Arrangement.Bottom

The vertical arrangement of the layout's children. This allows to add a spacing between items and specify the arrangement of the items when we have not enough of them to fill the whole minimum size.

horizontalAlignment: Alignment.Horizontal = Alignment.Start

the horizontal alignment applied to the items.

flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior()

logic describing fling behavior.

userScrollEnabled: Boolean = true

whether the scrolling via the user gestures or accessibility actions is allowed. You can still scroll programmatically using the state even when it is disabled

overscrollEffect: OverscrollEffect? = rememberOverscrollEffect()

the OverscrollEffect that will be used to render overscroll for this layout. Note that the OverscrollEffect.node will be applied internally as well - you do not need to use Modifier.overscroll separately.

content: LazyListScope.() -> Unit

a block which describes the content. Inside this block you can use methods like LazyListScope.item to add a single item or LazyListScope.items to add a list of items.

LazyLayoutScrollScope

fun LazyLayoutScrollScope(state: LazyListState, scrollScope: ScrollScope): LazyLayoutScrollScope

An implementation of LazyLayoutScrollScope that can be used with LazyLists. Please refer to the sample to learn how to use this API.

import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyLayoutScrollScope
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.layout.LazyLayoutScrollScope
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.State
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

suspend fun LazyListState.customScroll(block: suspend LazyLayoutScrollScope.() -> Unit) =
    scroll {
        block.invoke(LazyLayoutScrollScope(this@customScroll, this))
    }
val itemsList = (0..100).toList()
val state = rememberLazyListState()
val scope = rememberCoroutineScope()

Column(Modifier.verticalScroll(rememberScrollState())) {
    Button(
        onClick = {
            scope.launch {
                state.customScroll {
                    snapToItem(40, 0) // teleport to item 40
                    val distance = calculateDistanceTo(50).toFloat()
                    var previousValue = 0f
                    androidx.compose.animation.core.animate(
                        0f,
                        distance,
                        animationSpec = tween(5_000)
                    ) { currentValue, _ ->
                        previousValue += scrollBy(currentValue - previousValue)
                    }
                }
            }
        }
    ) {
        Text("Scroll To Item 50")
    }
    LazyRow(state = state) {
        items(itemsList) {
            Box(Modifier.padding(2.dp).background(Color.Red).size(45.dp)) {
                Text(it.toString())
            }
        }
    }
}
Parameters
state: LazyListState

The LazyListState associated with the layout where this custom scroll should be performed.

scrollScope: ScrollScope

The base ScrollScope where the scroll session was created.

Returns
LazyLayoutScrollScope

An implementation of LazyLayoutScrollScope that works with LazyRow and LazyColumn.

LazyListPrefetchStrategy

@ExperimentalFoundationApi
fun LazyListPrefetchStrategy(nestedPrefetchItemCount: Int = 2): LazyListPrefetchStrategy

Creates an instance of the default LazyListPrefetchStrategy, allowing for customization of the nested prefetch count.

Parameters
nestedPrefetchItemCount: Int = 2

specifies how many inner items should be prefetched when this LazyList is nested inside another LazyLayout. For example, if this is the state for a horizontal LazyList nested in a vertical LazyList, you might want to set this to the number of items that will be visible when this list is scrolled into view.

@Composable
fun LazyRow(
    modifier: Modifier = Modifier,
    state: LazyListState = rememberLazyListState(),
    contentPadding: PaddingValues = PaddingValues(0.dp),
    reverseLayout: Boolean = false,
    horizontalArrangement: Arrangement.Horizontal = if (!reverseLayout) Arrangement.Start else Arrangement.End,
    verticalAlignment: Alignment.Vertical = Alignment.Top,
    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
    userScrollEnabled: Boolean = true,
    overscrollEffect: OverscrollEffect? = rememberOverscrollEffect(),
    content: LazyListScope.() -> Unit
): Unit

The horizontally scrolling list that only composes and lays out the currently visible items. The content block defines a DSL which allows you to emit items of different types. For example you can use LazyListScope.item to add a single item and LazyListScope.items to add a list of items.

import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material.Text

val itemsList = (0..5).toList()
val itemsIndexedList = listOf("A", "B", "C")

LazyRow {
    items(itemsList) { Text("Item is $it") }

    item { Text("Single item") }

    itemsIndexed(itemsIndexedList) { index, item -> Text("Item at index $index is $item") }
}
Parameters
modifier: Modifier = Modifier

the modifier to apply to this layout

state: LazyListState = rememberLazyListState()

the state object to be used to control or observe the list's state

contentPadding: PaddingValues = PaddingValues(0.dp)

a padding around the whole content. This will add padding for the content after it has been clipped, which is not possible via modifier param. You can use it to add a padding before the first item or after the last one. If you want to add a spacing between each item use horizontalArrangement.

reverseLayout: Boolean = false

reverse the direction of scrolling and layout. When true, items are laid out in the reverse order and LazyListState.firstVisibleItemIndex == 0 means that row is scrolled to the end. Note that reverseLayout does not change the behavior of horizontalArrangement, e.g. with 123### becomes 321###.

horizontalArrangement: Arrangement.Horizontal = if (!reverseLayout) Arrangement.Start else Arrangement.End

The horizontal arrangement of the layout's children. This allows to add a spacing between items and specify the arrangement of the items when we have not enough of them to fill the whole minimum size.

verticalAlignment: Alignment.Vertical = Alignment.Top

the vertical alignment applied to the items

flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior()

logic describing fling behavior.

userScrollEnabled: Boolean = true

whether the scrolling via the user gestures or accessibility actions is allowed. You can still scroll programmatically using the state even when it is disabled.

overscrollEffect: OverscrollEffect? = rememberOverscrollEffect()

the OverscrollEffect that will be used to render overscroll for this layout. Note that the OverscrollEffect.node will be applied internally as well - you do not need to use Modifier.overscroll separately.

content: LazyListScope.() -> Unit

a block which describes the content. Inside this block you can use methods like LazyListScope.item to add a single item or LazyListScope.items to add a list of items.

rememberLazyListState

@Composable
fun rememberLazyListState(
    initialFirstVisibleItemIndex: Int = 0,
    initialFirstVisibleItemScrollOffset: Int = 0
): LazyListState

Creates a LazyListState that is remembered across compositions.

Changes to the provided initial values will not result in the state being recreated or changed in any way if it has already been created.

Parameters
initialFirstVisibleItemIndex: Int = 0

the initial value for LazyListState.firstVisibleItemIndex

initialFirstVisibleItemScrollOffset: Int = 0

the initial value for LazyListState.firstVisibleItemScrollOffset

rememberLazyListState

@ExperimentalFoundationApi
@Composable
fun rememberLazyListState(
    initialFirstVisibleItemIndex: Int = 0,
    initialFirstVisibleItemScrollOffset: Int = 0,
    prefetchStrategy: LazyListPrefetchStrategy = remember { LazyListPrefetchStrategy() }
): LazyListState

Creates a LazyListState that is remembered across compositions.

Changes to the provided initial values will not result in the state being recreated or changed in any way if it has already been created.

Parameters
initialFirstVisibleItemIndex: Int = 0

the initial value for LazyListState.firstVisibleItemIndex

initialFirstVisibleItemScrollOffset: Int = 0

the initial value for LazyListState.firstVisibleItemScrollOffset

prefetchStrategy: LazyListPrefetchStrategy = remember { LazyListPrefetchStrategy() }

the LazyListPrefetchStrategy to use for prefetching content in this list

Extension functions

inline fun <T : Any?> LazyListScope.items(
    items: Array<T>,
    noinline key: ((item) -> Any)? = null,
    noinline contentType: (item) -> Any? = { null },
    crossinline itemContent: @Composable LazyItemScope.(item) -> Unit
): Unit

Adds an array of items.

Parameters
items: Array<T>

the data array

noinline key: ((item) -> Any)? = null

a factory of stable and unique keys representing the item. Using the same key for multiple items in the list is not allowed. Type of the key should be saveable via Bundle on Android. If null is passed the position in the list will represent the key. When you specify the key the scroll position will be maintained based on the key, which means if you add/remove items before the current visible item the item with the given key will be kept as the first visible one. This can be overridden by calling 'requestScrollToItem' on the 'LazyListState'.

noinline contentType: (item) -> Any? = { null }

a factory of the content types for the item. The item compositions of the same type could be reused more efficiently. Note that null is a valid type and items of such type will be considered compatible.

crossinline itemContent: @Composable LazyItemScope.(item) -> Unit

the content displayed by a single item

inline fun <T : Any?> LazyListScope.items(
    items: List<T>,
    noinline key: ((item) -> Any)? = null,
    noinline contentType: (item) -> Any? = { null },
    crossinline itemContent: @Composable LazyItemScope.(item) -> Unit
): Unit

Adds a list of items.

Parameters
items: List<T>

the data list

noinline key: ((item) -> Any)? = null

a factory of stable and unique keys representing the item. Using the same key for multiple items in the list is not allowed. Type of the key should be saveable via Bundle on Android. If null is passed the position in the list will represent the key. When you specify the key the scroll position will be maintained based on the key, which means if you add/remove items before the current visible item the item with the given key will be kept as the first visible one. This can be overridden by calling 'requestScrollToItem' on the 'LazyListState'.

noinline contentType: (item) -> Any? = { null }

a factory of the content types for the item. The item compositions of the same type could be reused more efficiently. Note that null is a valid type and items of such type will be considered compatible.

crossinline itemContent: @Composable LazyItemScope.(item) -> Unit

the content displayed by a single item

itemsIndexed

inline fun <T : Any?> LazyListScope.itemsIndexed(
    items: Array<T>,
    noinline key: ((index: Int, item) -> Any)? = null,
    crossinline contentType: (index: Int, item) -> Any? = { _, _ -> null },
    crossinline itemContent: @Composable LazyItemScope.(index: Int, item) -> Unit
): Unit

Adds an array of items where the content of an item is aware of its index.

Parameters
items: Array<T>

the data array

noinline key: ((index: Int, item) -> Any)? = null

a factory of stable and unique keys representing the item. Using the same key for multiple items in the list is not allowed. Type of the key should be saveable via Bundle on Android. If null is passed the position in the list will represent the key. When you specify the key the scroll position will be maintained based on the key, which means if you add/remove items before the current visible item the item with the given key will be kept as the first visible one. This can be overridden by calling 'requestScrollToItem' on the 'LazyListState'.

crossinline contentType: (index: Int, item) -> Any? = { _, _ -> null }

a factory of the content types for the item. The item compositions of the same type could be reused more efficiently. Note that null is a valid type and items of such type will be considered compatible.

crossinline itemContent: @Composable LazyItemScope.(index: Int, item) -> Unit

the content displayed by a single item

inline fun <T : Any?> LazyListScope.itemsIndexed(
    items: List<T>,
    noinline key: ((index: Int, item) -> Any)? = null,
    crossinline contentType: (index: Int, item) -> Any? = { _, _ -> null },
    crossinline itemContent: @Composable LazyItemScope.(index: Int, item) -> Unit
): Unit

Adds a list of items where the content of an item is aware of its index.

Parameters
items: List<T>

the data list

noinline key: ((index: Int, item) -> Any)? = null

a factory of stable and unique keys representing the item. Using the same key for multiple items in the list is not allowed. Type of the key should be saveable via Bundle on Android. If null is passed the position in the list will represent the key. When you specify the key the scroll position will be maintained based on the key, which means if you add/remove items before the current visible item the item with the given key will be kept as the first visible one. This can be overridden by calling 'requestScrollToItem' on the 'LazyListState'.

crossinline contentType: (index: Int, item) -> Any? = { _, _ -> null }

a factory of the content types for the item. The item compositions of the same type could be reused more efficiently. Note that null is a valid type and items of such type will be considered compatible.

crossinline itemContent: @Composable LazyItemScope.(index: Int, item) -> Unit

the content displayed by a single item