Paging 3 — Easier Way to Pagination

Metin Ozcura
ProAndroidDev
Published in
4 min readJan 23, 2021

--

Source: Android Developers Blog

Most apps display a large list of data, however, users generally see only a small part of it, so fetching all of the list data from the network is not an optimum solution.

The Paging library is a much easier way to implement this approach. Currently, Paging 3 is available as an alpha release. If you want to use a stable version you can use Paging 2.

This post will be about Paging 3.

Source: Android Developers Blog

What’s new

Paging 3 comes with some considerable differences from the earlier versions. Some of them are:

  • Kotlin Coroutines support with Flow (also has support for LiveData with ListenableFuturePagingSource and RxJavawith RxPagingSource)
  • Built-in support for loading state headers and footers
  • List separators
  • Built-in support for the refreshing data, retry and error handling

Implementing Paging 3 in your app

Setup

Add the following dependencies to your app-level build.gradle file to import Paging 3 components.

dependencies {
def paging_version = "3.0.0-alpha12"

implementation "androidx.paging:paging-runtime:$paging_version"

// alternatively - without Android dependencies for tests
testImplementation "androidx.paging:paging-common:$paging_version"
}

Creating a Data Source

We have the option to get data and cache in a Room database to add an offline usage feature with a RemoteMediator. But this case will be in another post. In this post, PagingSource will be used to get data from The Rick and Morty API and show all the characters in the series using Paging 3.

Let’s start with creating the response model.

As you see in the PageInfo class, we have the number of pages, link to the next and previous keys. These keys will be used in the PagingSource will be created.

PagingSource

A PagingSource retrieves data from a single data source like network, local database, file, etc.

PagingSource takes two parameters, a key and a value. The Value parameter is the type of data that will be loaded and Key defines what data to load. E.g. Int as a page number or String as a next page token.

How load() function uses and updates the key. Source: Official Docs of Paging 3

The load() function should be implemented to retrieve data from the data source (network in our case). load() is a suspend function, so you can call other suspend functions here like a network call. For more information about suspend functions, check the Kotlin Coroutines docs.

  • If the getAllCharacters()request is successful, return the character list wrapped in a LoadResult.Page object and add the previous and next keys if they are available.
  • If the request fails, return the exception wrapped in a LoadResult.Error object containing info about the exception.

Pager

The container for the data returned from PagingSource is called PagingData. A Pager instance has to be created to build a PagingData stream. Three parameters are needed to create an instance. These are:

  • PagingSource is our data source created in the name CharactersPagingDataSource.
  • PagingConfig defines how to get data from the PagingSource like page size, prefetch distance, etc. Check official docs for the parameters you can set for PagingSource.
  • An optional initialKey to start loading with a default key.

Connect RecyclerView to the PagingData

A PagingDataAdapter should be implemented to consume PagingData.

The last step is collecting the PagingData object in our fragment or activity and set into the CharacterAdapter.

The RecyclerView now displays data coming from the data source and loads the next pages when the user scrolls to the end of the list.

Conclusion

The Paging 3 library provides first-class Kotlin support, designed to fit recommended Android app architecture and works seamlessly with other Jetpack components. It also can handle easy or complex data operations like data loading from the network, database, or a combination of different data sources.

In the next posts, I will write about headers and footers, list separators and use the Room database and network together with RemoteMediator.

--

--