PagedList

Added in 2.0.0
Deprecated in 3.0.0

Lazy loading list that pages in immutable content from a PagingSource.

A PagedList is a List which loads its data in chunks (pages) from a PagingSource. Items can be accessed with get, and further loading can be triggered with loadAround. To display a PagedList, see androidx.paging.PagedListAdapter, which enables the binding of a PagedList to a androidx.recyclerview.widget.RecyclerView.

Loading Data

All data in a PagedList is loaded from its PagingSource. Creating a PagedList loads the first chunk of data from the PagingSource immediately, and should for this reason be done on a background thread. The constructed PagedList may then be passed to and used on the UI thread. This is done to prevent passing a list with no loaded content to the UI thread, which should generally not be presented to the user.

A PagedList initially presents this first partial load as its content, and expands over time as content is loaded in. When loadAround is called, items will be loaded in near the passed list index. If placeholder nulls are present in the list, they will be replaced as content is loaded. If not, newly loaded items will be inserted at the beginning or end of the list.

PagedList can present data for an unbounded, infinite scrolling list, or a very large but countable list. Use PagedList.Config to control how many items a PagedList loads, and when.

If you use androidx.paging.LivePagedListBuilder to get a androidx.lifecycle.LiveData, it will initialize PagedLists on a background thread for you.

Placeholders

There are two ways that PagedList can represent its not-yet-loaded data - with or without null placeholders.

With placeholders, the PagedList is always the full size of the data set. get(N) returns the Nth item in the data set, or null if its not yet loaded.

Without null placeholders, the PagedList is the sublist of data that has already been loaded. The size of the PagedList is the number of currently loaded items, and get(N) returns the Nth loaded item. This is not necessarily the Nth item in the data set.

Placeholders have several benefits:

  • They express the full sized list to the presentation layer (often a androidx.paging.PagedListAdapter), and so can support scrollbars (without jumping as pages are loaded or dropped) and fast-scrolling to any position, loaded or not.

  • They avoid the need for a loading spinner at the end of the loaded list, since the list is always full sized.

They also have drawbacks:

  • Your Adapter needs to account for null items. This often means providing default values in data you bind to a androidx.recyclerview.widget.RecyclerView.ViewHolder.

  • They don't work well if your item views are of different sizes, as this will prevent loading items from cross-fading nicely.

  • They require you to count your data set, which can be expensive or impossible, depending on your PagingSource.

Placeholders are enabled by default, but can be disabled in two ways. They are disabled if the PagingSource does not count its data set in its initial load, or if false is passed to PagedList.Config.Builder.setEnablePlaceholders when building a PagedList.Config.

Mutability and Snapshots

A PagedList is mutable while loading, or ready to load from its PagingSource. As loads succeed, a mutable PagedList will be updated via Runnables on the main thread. You can listen to these updates with a PagedList.Callback. (Note that androidx.paging .PagedListAdapter will listen to these to signal RecyclerView about the updates/changes).

If a PagedList attempts to load from an invalid PagingSource, it will detach from the PagingSource, meaning that it will no longer attempt to load data. It will return true from isImmutable, and a new PagingSource / PagedList pair must be created to load further data.

See PagingSource and androidx.paging.LivePagedListBuilder for how new PagedLists are created to represent changed data.

A PagedList snapshot is simply an immutable shallow copy of the current state of the PagedList as a List. It will reference the same inner items, and contain the same null placeholders, if present.

Parameters
<T : Any>

The type of the entries in the list.

Summary

Nested types

Signals when a PagedList has reached the end of available data.

class PagedList.Builder<Key : Any, Value : Any>

This class is deprecated. PagedList is deprecated and has been replaced by PagingData, which no longer supports constructing snapshots of loaded data manually.

abstract class PagedList.Callback

Callback signaling when content is loaded into the list.

Configures how a PagedList loads content from its PagingSource.

Builder class for PagedList.Config.

Public functions

Unit

Adds a callback.

android
Unit
addWeakCallback(previousSnapshot: List<T>?, callback: PagedList.Callback)

This function is deprecated. Dispatching a diff since snapshot created is behavior that can be instead tracked by attaching a Callback to the PagedList that is mutating, and tracking changes since calling PagedList.snapshot().

android
Unit

Add a listener to observe the loading state of the PagedList.

android
abstract Unit

Detach the PagedList from its PagingSource, and attempt to load no more data.

android
open operator T?
get(index: Int)

Get the item in the list of loaded items at the provided index.

android
Unit
loadAround(index: Int)

Load adjacent items to passed index.

android
Unit

Removes a previously added callback.

android
Unit

Remove a previously registered load state listener.

android
open Unit

Retry any errors associated with this PagedList.

android
List<T>

Returns an immutable snapshot of the PagedList in its current state.

android

Public properties

PagedList.Config

Return the Config used to construct this PagedList.

android
DataSource<*, T>

This property is deprecated. DataSource is deprecated and has been replaced by PagingSource.

android
abstract Boolean

True if the PagedList has detached the PagingSource it was loading from, and will no longer load new data.

android
open Boolean

Returns whether the list is immutable.

android
abstract Any?

Return the key for the position passed most recently to loadAround.

android
Int

Returns the number of items loaded in the PagedList.

android
Int

Position offset of the data in the list.

android
open Int

Size of the list, including any placeholders (not-yet-loaded null padding).

android

Inherited functions

From java.util.AbstractCollection
open Boolean
android
open operator Boolean
android
open Boolean
android
open Boolean
android
open Boolean
remove(@RecentlyNullable element: T)
android
open Boolean
android
open Boolean
android
open Array<Any>
android
open Array<T>
android
open String
android
From java.util.AbstractList
open Boolean
add(element: T)
android
open Unit
add(index: Int, element: T)
android
open Boolean
addAll(index: Int, @RecentlyNonNull elements: Collection<T>)
android
open Unit
android
open operator Boolean
android
open Int
android
open Int
android
open operator MutableIterator<T>
android
open Int
android
open MutableListIterator<T>
android
open MutableListIterator<T>
android
open T
android
open Unit
removeRange(p0: Int, p1: Int)
android
open operator T
set(index: Int, element: T)
android
open MutableList<T>
@RecentlyNonNull
subList(fromIndex: Int, toIndex: Int)
android
From kotlin.collections.Collection
open Stream<T>
android
open Spliterator<T>
android
open Stream<T>
android
open Array<T>

This function is deprecated. This member is not fully supported by Kotlin compiler, so it may be absent or have different signature in next major version

android
From kotlin.collections.Iterable
open Unit
android
From kotlin.collections.MutableCollection
open Boolean
android
From kotlin.collections.MutableList
open Unit
android
open Unit
android

Inherited properties

From java.util.AbstractList
Int
android

Public functions

addWeakCallback

fun addWeakCallback(callback: PagedList.Callback): Unit

Adds a callback.

The callback is internally held as weak reference, so PagedList doesn't hold a strong reference to its observer, such as a androidx.paging.PagedListAdapter. If an adapter were held with a strong reference, it would be necessary to clear its PagedList observer before it could be GC'd.

Parameters
callback: PagedList.Callback

Callback to dispatch to.

addWeakCallback

fun addWeakCallback(previousSnapshot: List<T>?, callback: PagedList.Callback): Unit

Adds a callback, and issues updates since the previousSnapshot was created.

If previousSnapshot is passed, the callback will also immediately be dispatched any differences between the previous snapshot, and the current state. For example, if the previousSnapshot was of 5 nulls, 10 items, 5 nulls, and the current state was 5 nulls, 12 items, 3 nulls, the callback would immediately receive a call ofonChanged(14, 2).

This allows an observer that's currently presenting a snapshot to catch up to the most recent version, including any changes that may have been made.

The callback is internally held as weak reference, so PagedList doesn't hold a strong reference to its observer, such as a PagedListAdapter. If an adapter were held with a strong reference, it would be necessary to clear its PagedList observer before it could be GC'd.

Parameters
previousSnapshot: List<T>?

Snapshot previously captured from this List, or null.

callback: PagedList.Callback

PagedList.Callback to dispatch to.

addWeakLoadStateListener

fun addWeakLoadStateListener(listener: (LoadType, LoadState) -> Unit): Unit

Add a listener to observe the loading state of the PagedList.

Parameters
listener: (LoadType, LoadState) -> Unit

Listener to receive updates.

detach

abstract fun detach(): Unit

Detach the PagedList from its PagingSource, and attempt to load no more data.

This is called automatically when a PagingSource is observed to be invalid, which is a signal to stop loading. The PagedList will continue to present existing data, but will not initiate new loads.

get

open operator fun get(index: Int): T?

Get the item in the list of loaded items at the provided index.

Parameters
index: Int

Index in the loaded item list. Must be >= 0, and <size

Returns
T?

The item at the passed index, or null if a null placeholder is at the specified position.

See also
size

loadAround

fun loadAround(index: Int): Unit

Load adjacent items to passed index.

Parameters
index: Int

Index at which to load.

Throws
kotlin.IndexOutOfBoundsException

if index is not within bounds.

removeWeakCallback

fun removeWeakCallback(callback: PagedList.Callback): Unit

Removes a previously added callback.

Parameters
callback: PagedList.Callback

Callback, previously added.

See also
addWeakCallback

removeWeakLoadStateListener

fun removeWeakLoadStateListener(listener: (LoadType, LoadState) -> Unit): Unit

Remove a previously registered load state listener.

Parameters
listener: (LoadType, LoadState) -> Unit

Previously registered listener.

retry

open fun retry(): Unit

Retry any errors associated with this PagedList.

If for example a network PagingSource append timed out, calling this method will retry the failed append load.

You can observe loading state via addWeakLoadStateListener, though generally this is done through the PagedListAdapter or AsyncPagedListDiffer.

snapshot

fun snapshot(): List<T>

Returns an immutable snapshot of the PagedList in its current state.

If this is immutableisImmutable due to its PagingSource being invalid, it will be returned.

Returns
List<T>

Immutable snapshot of PagedList data.

Public properties

config

val configPagedList.Config

Return the Config used to construct this PagedList.

Returns
PagedList.Config

the Config of this PagedList

dataSource

val dataSourceDataSource<*, T>
Throws
kotlin.IllegalStateException

if this PagedList was instantiated without a wrapping a backing DataSource

isDetached

abstract val isDetachedBoolean

True if the PagedList has detached the PagingSource it was loading from, and will no longer load new data.

A detached list is immutable.

Returns
Boolean

true if the data source is detached.

isImmutable

open val isImmutableBoolean

Returns whether the list is immutable.

Immutable lists may not become mutable again, and may safely be accessed from any thread.

In the future, this method may return true when a PagedList has completed loading from its PagingSource. Currently, it is equivalent to isDetached.

Returns
Boolean

true if the PagedList is immutable.

lastKey

abstract val lastKeyAny?

Return the key for the position passed most recently to loadAround.

When a PagedList is invalidated, you can pass the key returned by this function to initialize the next PagedList. This ensures (depending on load times) that the next PagedList that arrives will have data that overlaps. If you use androidx.paging.LivePagedListBuilder, it will do this for you.

Returns
Any?

Key of position most recently passed to loadAround.

loadedCount

val loadedCountInt

Returns the number of items loaded in the PagedList.

Unlike size this counts only loaded items, not placeholders.

If placeholders are disabled, this method is equivalent to size.

Returns
Int

Number of items currently loaded, not counting placeholders.

See also
size

positionOffset

val positionOffsetInt

Position offset of the data in the list.

If the PagingSource backing this PagedList is counted, the item returned from get(i) has a position in the original data set of i + getPositionOffset().

If placeholders are enabled, this value is always 0, since get(i) will return either the data in its original index, or null if it is not loaded.

size

open val sizeInt

Size of the list, including any placeholders (not-yet-loaded null padding).

To get the number of loaded items, not counting placeholders, use loadedCount.

See also
loadedCount