Paging — Android Architecture Components
A couple of weeks back the team at Google released a slick library to address a common use case, that of pagination. This seems to be in line with their recent efforts to stream line development and reduce developer effort. Handling an infinite scrolling list can be a pain and brings about more boilerplate concerns which are being addressed in this library. This post is part of series of working with Paging, first skimming over the basics, then moving over to getting the most out of it.
Typically when displaying a huge list of items one can either choose
- To partition the data as a sequence to be loaded one by one (Contiguous data load, This is the more common use case)
- Skip directly to a particular element in the data set and load the stuff around this (A typical use case is where data has certain sections whose start is demarcated. Lets say a contacts app where you skip from ‘A’ to ‘F’)
The paging library consists mainly of these following components
- DataSource : This is the component responsible for loading data elements. This would depending on the usage have callbacks to load before/after an index or just a range of items.
- PagedList: A wrapper list that holds your data items and invokes the data source to load elements. Paged list typically houses the two executors background and foreground on which the tasks like data source loads and view updations happen respectively.
- PagedListAdapter: This basically a slightly modified version of your RecyclerView adapter that internally uses a helper(PagedListAdapterHelper) to do the grunt work.
For the purpose of this introductory post we would use KeyedDataSource which represents a source that can facilitate loading pages in a sequential manner. Lets take a dive into some code
Gradle Import
implementation "android.arch.paging:runtime:1.0.0-alpha2"
SequentialDataSource
This class provides the requisite data via a simple MockDataProvider that’s backed by finite ArrayList of items. One could make synchronous network calls here since “loadBefore” and “loadAfter” are executed on the background thread.
MyPagedListAdapter
This class provides the usual view inflation and bindings. Notice the class extends PageListAdapter and does not override the usual getItemCount() as this is provided by the PageList object. The adapter takes a DiffCallback object construction parameter; This is used to help in consolidating changes between two lists and avoid using notifyDataSetChanged for the not so straightforward changes in your adapter data.
For those of you who have heard of DiffUtils/DiffCallbacks for the first time take a look at this great article on DiffUtil by Mert.
Almost done now just some wiring up and configuration left in the activity.
PageList takes in 4 important parameters
- The Config object contains configurable fields like placeholder support, initial load size, page size etc. (Much of these will be covered in subsequent articles).
- The DataSource is merely an instance our earlier defined class.
- A foreground executor instance which wraps around our main thread via a Handler.
- A background executor instance which is backed by a Thread pool of a fixed size.
We attach this page list to the adapter via the setList method and stitch everything together.
Thats it! In the upcoming articles we’ll see about using this effectively via LiveData, working with non contiguous data sets and configuring it in a more appealing fashion.
Ps: You can find the entire project on Github