Android Jetpack: Paging
Articles Blog

Android Jetpack: Paging

August 22, 2019

work with large sets of data, but only need to
load and display a small portion
at any given time. If you’re not careful,
you might request data you don’t actually need,
wasting your user’s battery and bandwidth. If the data you are displaying
is constantly updating, it can be difficult to
keep your UI in sync and still send only a
small amount of information over the network. The Paging Library–
part of Jetpack– tackles these problems,
enabling you to load data gradually and gracefully. The library supports both
large but bounded lists, as well as lists
of unbounded sites, such as
continuously-updating feeds. It offers integration
with RecyclerView, which is typically used
to display large data sets and plays nicely with
either LiveData or RxJava for observing new
data in your UI. The paging library is based
on the idea of sending lists to the UI with the live data
of a list that is observed by the RecyclerView adapter. It then builds up on this
idea by adding paging so you can load
content gradually. Let’s go over the main
components of the library, and see how they fit in
your app’s architecture. The core elements in
the Paging Library are the PagedList
and the DataSource. A PagedList is a collection
that loads data in chunks, known as pages, asynchronously. A DataSource is the base class
for loading snapshots of data into a give page list. Data sources can be backed by
the network, database, file, or anywhere you want
to retrieve data from. You create the DataSource using
a DataSource.Factory object. The Paging Library also
provides a PagedListAdapter which helps you present
data from PagedList in a RecyclerView. The PagedListAdapter is
notified when pages are loaded, and it uses DiffUtil to
compute fine grain updates as new data is received. The Paging Library provides
the LivePagedListBuilder class for getting a LiveData
object of type PagedList. To create a
LivePagedListBuilder, pass in the dataSourceFactory
object and a paging configuration. If you prefer working with
RxJava instead of LiveData, then just use the
RxPagedListBuilder. It’s constructed similarly
to LivePagedListBuilder, but instead of a
live data object, it will return an
observable or flowable depending on what you need. Let’s take a look at some
common scenarios of loading data from a database or a
retrofit-based network source, and see how the
Paging Library helps. So, first case, let’s
say that the database is your DataSource. The Room Persistence library
provides native support for Paging Library data sources. For a given query,
Room allows you to return a DataSource.Factory
from the Dao, and handles the implementation
of the DataSource for you. Second case. Let’s say that the
database is a cache for data loaded from network. So here you would still
return a DataSource.Factory from the Dao, but
you will also need to implement another paging
component, a boundary callback. The boundary callback
loads more data when the user gets near
the end of the data that’s in the local cache. After the data is inserted, the
paging library automatically updates the UI. But don’t forget to associate
the boundary callback with the live PagedListBuilder
you created earlier. That way it can be
used by the PagedList. Third case. Having only the network
as your DataSource. Here you will have to
create both your DataSource and your DataSource.Factory. But when choosing which
data source type to extend, consider what your
backend API looks like. If you need to request data from
your backend based on a key, you will extend from
ItemKeyedDataSource. Let’s take an example. You might need to
get the first 100 comments added to
a GitHub repository after a certain date. Then the date will be the
key for your DataSource. ItemKeyedDataSource
allows you to define how to load the
initial page, as well as how to load items both
after and before a keyed entry. If your backend exposes
APIs that work with pages, then you would extend
from PageKeyedDataSource. For example the search
repositories GitHub API returns paginated items. In the GitHub API
request, you need to specify the query,
which page you want, and optionally, the
number of items per page. And dependent on how you create
your network data source, you will need to implement a
DataSource.Factory that knows how to create your data source. For full examples of how to
implement all of these cases, including how to handle error
cases or retry mechanisms, check out our samples on GitHub. OK, let’s sum it up. Here’s what you’ll need
to do to integrate paging. You’ll need to define
your DataSource, create a boundary
callback if it’s needed, create a LiveData of a
PagedList with the help of a LivePagedListBuilder,
update your adapter to be a PagedListAdapter,
and then finally observe the LiveData a
PagedList in your UI, and send the PagedList
to your adapter. That’s it. Just five steps. Check out our documentation,
code samples, and collab, and start using
the Paging Library to provide smooth-performing
lists for your users.

Only registered users can comment.

  1. Great set of videos! Please improve your indentation on the slides or use an IDE.. It's easier to process something new if it's well indented..

  2. Once you started showing your examples as Kotlin only, it got really annoying and hard to understand :/

  3. I understood practically none of this. I understand what it's trying to do but I'm not sure if I could implement it.

  4. Why do you show all of your examples in Kotlin?
    Kotlin isn't made by Google and we all know that Android development is slowly moving towards Flutter. Then why Kotlin? And this language isn't popular like Java.

  5. Some questions:
    1. Will this work even with 2 sided paged RecyclerView? Meaning loading extra data at the top and/or at the bottom?
    2. What is "pageSize" ? What if it's unknown, and the app just needs to take what it's given? Meaning that each time when I give it a bulk of items, it should show only them?
    3. What can I do to put items at the top and bottom (edges of the current page), to show that it's loading, in case the user has reached them ?

  6. Am I the only one that watches every single video android releases but still has no idea what are we gonna dooo. I seriously don't know how to use android I just use Google to copy and paste the functionality I want.

  7. Yay Kotlin! The slides would be way easier to read without the giant font size though. When you split what belongs on one line of code into 4+ lines, it makes it really hard to parse.

  8. Kotlin sucks! It's non intuitive and moronic. Please stop using it already. It sucks more than Snooki from Jersey shore

  9. This library is honestly terrible. Here I was looking for an easy-to-implement EndlessRecyclerAdapter only to sift through crap documentation and find out that this is an incredibly messy alternative.

  10. So many people complaining about examples only in Kotlin. Syntax is not that different… If you don't want to learn new languages why are you even a developer?

  11. Developers, when we understand that developers are allowed uses. it become more famiiar with Androids are being used.

  12. To understand this I need to learn Kotlin. But by the time I have learnt Kotlin, I suspect most of what is in this video will have changed or been made obsolete. Since Kotlin solves none of my present concerns about Android, I think I will look at Flutter and see if that makes app development fun again…

  13. When my app loads for the first time, onZeroItemsLoaded is called and the sample says I should request data and save it into the database. But If I save it into the database, the sample does not show how to update the livedata with this new value

  14. Seriously Google, 10 years on and Android is just getting more and more complex. Stop this nonsense and start investing in simplified solutions.

  15. It's a complex use case and I'm not surprised the api has a degree of complexity as well. Dive right in and it might be easier than you think.

Leave a Reply

Your email address will not be published. Required fields are marked *