Android RecyclerView Pagination with Paging Library(PositionalDataSource) using Retrofit, MVVM, LiveData, Room

Anto Beslie
4 min readApr 7, 2019

--

To implement Pagination in RecyclerView, we used to add a lot of heavy logic to give a smooth experience to the user. Paging Library introduced by Google as part of the Android Architecture Components, provides an easier and much smoother way to handle pagination which will handle all paging logic.

Paging Library has three components as follows :

To get a deeper understanding of this library and the components, you can refer this post by Mohd Saqyuib. He has given an excellent explanation and an example with PageKeyedDataSource.

In this post, I will be implementing the pagination with PostionalDataSource Component.

PositionalDataSource is helpful when you have to load the data with a size and a start position.
Eg. {start_position : 0, load_size : 10}, {start_position : 10, load_size : 10}, {start_position : 20, load_size : 10}…

Application Overview :
Get location from user and populate the nearby restaurants using the Zomato Api. Scrolling down, perform pagination.
If the user searches from the search bar, then search from the list already loaded. If no results are found, then hit the Zomato Api with the search term and fetch the results.

Let’s start the coding part.

To integrate Paging Library, add this to your app’s gradle.

implementation 'android.arch.paging:runtime:1.0.1'

I am using Retrofit to fetch the data from the API and Room to store the data.

RetroApi.java
Your RetroApi interface is these having query parameters.
lat, lon -> latitude and longitude
start -> Starting Postion
count -> fixed size of list to be loaded
sort -> Sort by ‘real_distance’ which will be a constant value here
search -> search string to search restaurants with the search term entered by user

ShopsModel.java
A POJO class created with the above request parameters to be passed across which has the inputs from user/activity

Now we will create the Room Repository to save the required data to be displayed in the list.

Repository Classes
ShopsData.java(Table)

public static DiffUtil.ItemCallback<ShopsData> DIFF_CALLBACK = new DiffUtil.ItemCallback<ShopsData>() {
@Override
public boolean areItemsTheSame(@NonNull ShopsData shopsData, @NonNull ShopsData t1) {
return shopsData.id == t1.id;
}
@Override
public boolean areContentsTheSame(@NonNull ShopsData shopsData, @NonNull ShopsData t1) {
return shopsData.equals(t1);
}
};

The above snippet to compare objects is added to the class as PagedListAdapter will use this comparison function to check whether the last loaded data is same as the new one or not to avoid conflicts.
You will see the usage in the class ShopsListAdapter.java.

ShopsDao.java

ShopsRepository.java

PagingLibrary Classes
ShopsDataSource.java

This is the where the PositionalDataSource component comes into action. On extending the PostionalDataSource class, LoadIntial and LoadRange functions are called.
LoadInital : The First call with initial parameters to get the overall size of the list. computeInitialLoadPosition,computeInitialLoadSize will calculate the initial position and size to be passed as parameters to the API retro call. On successful response, we pass the total count of list items to the callback function along with the data list we have obtained. The same data will be inserted to the Room Database we have created to use in the search.
LoadRange : This will be called after LoadInitial to load the rest of the list items from the api. On successful response, we pass the data list alone to the callback function. The same data will be inserted to the Room Database we have created to use in the search.

ShopsDataSourceFactory.java
DataSource.Factory class passes data to ShopsDataSource class and fetches the returned data

Now let’s create the PagedListAdapter to populate the loaded data to the Recylerview.

ShopsListAdapter.java

As of now the fetching and populating data is almost over. Now let’s look at how our ViewModel class will be.

ShopsViewModel.java

ShopsViewModelFactory.java
We pass the request POJO class ShopsModel to the ViewModel using the ViewModelFactory class

Now let’s see how everything is brought together in the activity.

ShopsActivity
The page contains an action bar, search bar and RecylerView inside a SwipeRefreshLayout

ShopsActivity.java
Latitude and Longitude is received from the previous activity.
Every time activity is started or refreshed or search is done by the user, the ShopsModel is updated and sent to the ViewModel. The previous data will be invalidated and the DataSource will be called again fresh.

This way the pagination runs smoothly, search results are faster and user doesn’t feel any lag in any of the process. Also you can see the way I have handled the loading by observing a MutableLiveData variable networkState.

You can view/download the whole source source code here. Along with the above things, I have used Paces SDK and Loactions API to get the location from the user.

That’s all folks. If you find this article helpful leave a clap and share your thoughts/questions in the comments.

--

--