PagingData

class PagingData<T : Any>
kotlin.Any
   ↳ androidx.paging.PagingData

Container for Paged data from a single generation of loads.

Each refresh of data (generally either pushed by local storage, or pulled from the network) will have a separate corresponding PagingData.

Summary

Public methods
PagingData<T>
filter(predicate: (T) -> Boolean)

Returns a PagingData containing only elements matching the given predicate

PagingData<R>
flatMap(transform: (T) -> Iterable<R>)

Returns a PagingData of all elements returned from applying the given transform to each element, as it is loaded.

PagingData<T>

Returns a PagingData containing each original element, with the passed footer item added to the end of the list.

PagingData<T>

Returns a PagingData containing each original element, with the passed header item added to the start of the list.

PagingData<R>
map(transform: (T) -> R)

Returns a PagingData containing the result of applying the given transform to each element, as it is loaded.

Companion functions
PagingData<T>

PagingData<R>
insertSeparators(pagingData: PagingData<T>, generator: (T?, T?) -> R?)

Returns a PagingData containing each original element, with an optional separator generated by generator, given the elements before and after (or null, in boundary conditions).

Extension functions
From androidx.paging
PagingData<R>
PagingData<T>.insertSeparators(generator: (T?, T?) -> R?)

Returns a PagingData containing each original element, with an optional separator generated by generator, given the elements before and after (or null, in boundary conditions).

Public methods

filter

@CheckResult fun filter(predicate: (T) -> Boolean): PagingData<T>

Returns a PagingData containing only elements matching the given predicate

flatMap

@CheckResult fun <R : Any> flatMap(transform: (T) -> Iterable<R>): PagingData<R>

Returns a PagingData of all elements returned from applying the given transform to each element, as it is loaded.

insertFooterItem

@CheckResult fun insertFooterItem(item: T): PagingData<T>

Returns a PagingData containing each original element, with the passed footer item added to the end of the list.

The footer item is added to a loaded page which marks the end of the data stream in the append direction, either by returning null in PagingSource.LoadResult.Page.nextKey. It will be removed if the first page in the list is dropped, which can happen in the case of loaded* pages exceeding PagedList.Config.maxSize.

Note: This operation is not idempotent, calling it multiple times will continually add more footers to the end of the list, which can be useful if multiple footer items are required.

See Also

insertHeaderItem

@CheckResult fun insertHeaderItem(item: T): PagingData<T>

Returns a PagingData containing each original element, with the passed header item added to the start of the list.

The header item is added to a loaded page which marks the end of the data stream in the prepend direction by returning null in PagingSource.LoadResult.Page.prevKey. It will be removed if the first page in the list is dropped, which can happen in the case of loaded pages exceeding PagedList.Config.maxSize.

Note: This operation is not idempotent, calling it multiple times will continually add more headers to the start of the list, which can be useful if multiple header items are required.

See Also

map

@CheckResult fun <R : Any> map(transform: (T) -> R): PagingData<R>

Returns a PagingData containing the result of applying the given transform to each element, as it is loaded.

Companion functions

empty

@JvmStatic fun <T : Any> empty(): PagingData<T>

insertSeparators

@JvmStatic @CheckResult fun <T : R, R : Any> insertSeparators(
    pagingData: PagingData<T>,
    generator: (T?, T?) -> R?
): PagingData<R>

Returns a PagingData containing each original element, with an optional separator generated by generator, given the elements before and after (or null, in boundary conditions).

Note that this transform is applied asynchronously, as pages are loaded. Potential separators between pages are only computed once both pages are loaded.

Kotlin callers should instead use the extension function insertSeparators

/*
 * Create letter separators in an alphabetically sorted list.
 *
 * For example, if the input is:
 *     "apple", "apricot", "banana", "carrot"
 *
 * The operator would output:
 *     "A", "apple", "apricot", "B", "banana", "C", "carrot"
 */
pagingDataStream.map((pagingData) ->
        // map outer stream, so we can perform transformations on each paging generation
        PagingData.insertSeparators(pagingData,
                (@Nullable String before, @Nullable String after) -> {
                    if (after != null && (before == null
                            || before.charAt(0) != after.charAt(0))) {
                        // separator - after is first item that starts with its first letter
                        return Character.toString(Character.toUpperCase(after.charAt(0)));
                    } else {
                        // no separator - either end of list, or first
                        // letters of items are the same
                        return null;
                    }
                }));

/*
 * Create letter separators in an alphabetically sorted list of Items, with UiModel objects.
 *
 * For example, if the input is (each an `Item`):
 *     "apple", "apricot", "banana", "carrot"
 *
 * The operator would output a list of UiModels corresponding to:
 *     "A", "apple", "apricot", "B", "banana", "C", "carrot"
 */
pagingDataStream.map((itemPagingData) -> {
    // map outer stream, so we can perform transformations on each paging generation

    // first convert items in stream to UiModel.Item
    PagingData<UiModel.ItemModel> itemModelPagingData =
            itemPagingData.map(UiModel.ItemModel::new);

    // Now insert UiModel.Separators, which makes the PagingData of generic type UiModel
    return PagingData.insertSeparators(
            itemModelPagingData,
            (@Nullable UiModel.ItemModel before, @Nullable UiModel.ItemModel after) -> {
                if (after != null && (before == null
                        || before.item.label.charAt(0) != after.item.label.charAt(0))) {
                    // separator - after is first item that starts with its first letter
                    return new UiModel.SeparatorModel(
                            Character.toUpperCase(after.item.label.charAt(0)));
                } else {
                    // no separator - either end of list, or first
                    // letters of items are the same
                    return null;
                }
            });
});

public class UiModel {
    static class ItemModel extends UiModel {
        public Item item;
        ItemModel(Item item) {
            this.item = item;
        }
    }
    static class SeparatorModel extends UiModel {
        public char character;
        SeparatorModel(char character) {
            this.character = character;
        }
    }
}