LazyPagingItems


The class responsible for accessing the data from a Flow of PagingData. In order to obtain an instance of LazyPagingItems use the collectAsLazyPagingItems extension method of Flow with PagingData. This instance can be used for Lazy foundations such as LazyListScope.items to display data received from the Flow of PagingData.

Previewing LazyPagingItems is supported on a list of mock data. See sample for how to preview mock data.

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.sp
import androidx.paging.PagingData
import androidx.paging.compose.collectAsLazyPagingItems

/**
 * The composable that displays data from LazyPagingItems.
 *
 * This composable is inlined only for the purposes of this sample. In production code,
 * this function should be its own top-level function.
 */
@Composable
fun DisplayPaging(flow: Flow<PagingData<String>>) {
    // Flow of real data i.e. flow from a ViewModel, or flow of fake data i.e. from a Preview.
    val lazyPagingItems = flow.collectAsLazyPagingItems()
    LazyColumn(modifier = Modifier
        .fillMaxSize()
        .background(Color.Red)) {
        items(count = lazyPagingItems.itemCount) { index ->
            val item = lazyPagingItems[index]
            Text(text = "$item", fontSize = 35.sp, color = Color.Black)
        }
    }
}

/**
 * The preview function should be responsible for creating the fake data and passing it to the
 * function that displays it.
 */
// create list of fake data for preview
val fakeData = List(10) { "preview item $it" }
// create pagingData from a list of fake data
val pagingData = PagingData.from(fakeData)
// pass pagingData containing fake data to a MutableStateFlow
val fakeDataFlow = MutableStateFlow(pagingData)
// pass flow to composable
DisplayPaging(flow = fakeDataFlow)
Parameters
<T : Any>

the type of value used by PagingData.

Summary

Public functions

operator T?
get(index: Int)

Returns the presented item at the specified position, notifying Paging of the item access to trigger any loads necessary to fulfill prefetchDistance.

Cmn
T?
peek(index: Int)

Returns the presented item at the specified position, without notifying Paging of the item access that would normally trigger page loads.

Cmn
Unit

Refresh the data presented by this LazyPagingItems.

Cmn
Unit

Retry any failed load requests that would result in a LoadState.Error update to this LazyPagingItems.

Cmn

Public properties

Int

The number of items which can be accessed.

Cmn
ItemSnapshotList<T>

Contains the immutable ItemSnapshotList of currently presented items, including any placeholders if they are enabled.

Cmn
CombinedLoadStates

A CombinedLoadStates object which represents the current loading state.

Cmn

Extension functions

(index: Int) -> Any?
<T : Any> LazyPagingItems<T>.itemContentType(
    contentType: ((@<Error class: unknown class> item) -> Any?)?
)

Returns a factory for the content type of the item.

Cmn
(index: Int) -> Any
<T : Any> LazyPagingItems<T>.itemKey(
    key: ((@<Error class: unknown class> item) -> Any)?
)

Returns a factory of stable and unique keys representing the item.

Cmn

Public functions

get

operator fun get(index: Int): T?

Returns the presented item at the specified position, notifying Paging of the item access to trigger any loads necessary to fulfill prefetchDistance.

See also
peek

peek

fun peek(index: Int): T?

Returns the presented item at the specified position, without notifying Paging of the item access that would normally trigger page loads.

Parameters
index: Int

Index of the presented item to return, including placeholders.

Returns
T?

The presented item at position index, null if it is a placeholder

refresh

fun refresh(): Unit

Refresh the data presented by this LazyPagingItems.

refresh triggers the creation of a new PagingData with a new instance of PagingSource to represent an updated snapshot of the backing dataset. If a RemoteMediator is set, calling refresh will also trigger a call to RemoteMediator.load with REFRESH to allow RemoteMediator to check for updates to the dataset backing PagingSource.

Note: This API is intended for UI-driven refresh signals, such as swipe-to-refresh. Invalidation due repository-layer signals, such as DB-updates, should instead use PagingSource.invalidate.

See also
PagingSource.invalidate

retry

fun retry(): Unit

Retry any failed load requests that would result in a LoadState.Error update to this LazyPagingItems.

Unlike refresh, this does not invalidate PagingSource, it only retries failed loads within the same generation of PagingData.

LoadState.Error can be generated from two types of load requests:

  • PagingSource.load returning PagingSource.LoadResult.Error

  • RemoteMediator.load returning RemoteMediator.MediatorResult.Error

Public properties

itemCount

val itemCountInt

The number of items which can be accessed.

itemSnapshotList

val itemSnapshotListItemSnapshotList<T>

Contains the immutable ItemSnapshotList of currently presented items, including any placeholders if they are enabled. Note that similarly to peek accessing the items in a list will not trigger any loads. Use get to achieve such behavior.

loadState

val loadStateCombinedLoadStates

A CombinedLoadStates object which represents the current loading state.

Extension functions

itemContentType

fun <T : Any> LazyPagingItems<T>.itemContentType(
    contentType: ((@<Error class: unknown class> item) -> Any?)? = null
): (index: Int) -> Any?

Returns a factory for the content type of the item.

ContentTypes are generated with the contentType lambda that is passed in. If null is passed in, contentType of all items will default to null. If PagingConfig.enablePlaceholders is true, LazyPagingItems may return null items. Null items will automatically default to placeholder contentType.

This factory can be applied to Lazy foundations such as LazyGridScope.items or Pagers. Examples:

import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.paging.compose.collectAsLazyPagingItems
import androidx.paging.compose.itemContentType
import androidx.paging.compose.itemKey

val lazyPagingItems = pager.collectAsLazyPagingItems()

LazyVerticalGrid(columns = GridCells.Fixed(2)) {
    items(
        count = lazyPagingItems.itemCount,
        key = lazyPagingItems.itemKey { it },
        contentType = lazyPagingItems.itemContentType { "MyPagingItems" }
    ) { index ->
        val item = lazyPagingItems[index]
        PagingItem(item = item)
    }
}
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.Text
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.paging.compose.collectAsLazyPagingItems
import androidx.paging.compose.itemContentType
import androidx.paging.compose.itemKey

val lazyPagingItems = pager.collectAsLazyPagingItems()

LazyColumn {
    stickyHeader(
        key = "Header",
        contentType = "My Header",
    ) {
        Box(
            modifier = Modifier
                .padding(bottom = 10.dp)
                .background(Color.Red)
                .fillMaxWidth(),
            contentAlignment = Alignment.Center
        ) {
            Text(text = "Header", fontSize = 32.sp)
        }
    }
    items(
        count = lazyPagingItems.itemCount,
        key = lazyPagingItems.itemKey { it },
        contentType = lazyPagingItems.itemContentType { "MyPagingItems" }
    ) { index ->
        val item = lazyPagingItems[index]
        PagingItem(item = item)
    }
}
Parameters
contentType: ((@<Error class: unknown class> 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.

fun <T : Any> LazyPagingItems<T>.itemKey(
    key: ((@<Error class: unknown class> item) -> Any)? = null
): (index: Int) -> Any

Returns a factory of stable and unique keys representing the item.

Keys are generated with the key lambda that is passed in. If null is passed in, keys will default to a placeholder key. If PagingConfig.enablePlaceholders is true, LazyPagingItems may return null items. Null items will also automatically default to a placeholder key.

This factory can be applied to Lazy foundations such as LazyGridScope.items or Pagers. Examples:

import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PageSize
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.paging.Pager
import androidx.paging.compose.collectAsLazyPagingItems
import androidx.paging.compose.itemKey

val lazyPagingItems = pager.collectAsLazyPagingItems()
val pagerState = rememberPagerState { lazyPagingItems.itemCount }

HorizontalPager(
    modifier = Modifier.fillMaxSize(),
    state = pagerState,
    pageSize = PageSize.Fixed(200.dp),
    key = lazyPagingItems.itemKey { it }
) { index ->
    val item = lazyPagingItems[index]
    PagingItem(item = item)
}
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.paging.compose.collectAsLazyPagingItems
import androidx.paging.compose.itemContentType
import androidx.paging.compose.itemKey

val lazyPagingItems = pager.collectAsLazyPagingItems()

LazyVerticalGrid(columns = GridCells.Fixed(2)) {
    items(
        count = lazyPagingItems.itemCount,
        key = lazyPagingItems.itemKey { it },
        contentType = lazyPagingItems.itemContentType { "MyPagingItems" }
    ) { index ->
        val item = lazyPagingItems[index]
        PagingItem(item = item)
    }
}
Parameters
key: ((@<Error class: unknown class> 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. 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.