All examples of the new paging library have been with Room library and Room creates a Data Source for us. In my own case, I need to create my custom data source.
Here is
You can create a Custom Data Source, usually we built backend API to fetch data that takes pagenumber as a parameter to return the specified page.
For this situation you can use PageKeyedDataSource. Here is a sample code of PageKeyedDataSource using the StackOverflow API. The below code is using Retrofit to get the data from the StackOverflow API.
public class ItemDataSource extends PageKeyedDataSource {
//the size of a page that we want
public static final int PAGE_SIZE = 50;
//we will start from the first page which is 1
private static final int FIRST_PAGE = 1;
//we need to fetch from stackoverflow
private static final String SITE_NAME = "stackoverflow";
//this will be called once to load the initial data
@Override
public void loadInitial(@NonNull LoadInitialParams params, @NonNull final LoadInitialCallback callback) {
RetrofitClient.getInstance()
.getApi().getAnswers(FIRST_PAGE, PAGE_SIZE, SITE_NAME)
.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
if (response.body() != null) {
callback.onResult(response.body().items, null, FIRST_PAGE + 1);
}
}
@Override
public void onFailure(Call call, Throwable t) {
}
});
}
//this will load the previous page
@Override
public void loadBefore(@NonNull final LoadParams params, @NonNull final LoadCallback callback) {
RetrofitClient.getInstance()
.getApi().getAnswers(params.key, PAGE_SIZE, SITE_NAME)
.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
//if the current page is greater than one
//we are decrementing the page number
//else there is no previous page
Integer adjacentKey = (params.key > 1) ? params.key - 1 : null;
if (response.body() != null) {
//passing the loaded data
//and the previous page key
callback.onResult(response.body().items, adjacentKey);
}
}
@Override
public void onFailure(Call call, Throwable t) {
}
});
}
//this will load the next page
@Override
public void loadAfter(@NonNull final LoadParams params, @NonNull final LoadCallback callback) {
RetrofitClient.getInstance()
.getApi()
.getAnswers(params.key, PAGE_SIZE, SITE_NAME)
.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
if (response.body() != null) {
//if the response has next page
//incrementing the next page number
Integer key = response.body().has_more ? params.key + 1 : null;
//passing the loaded data and next page value
callback.onResult(response.body().items, key);
}
}
@Override
public void onFailure(Call call, Throwable t) {
}
});
}
}
Here you can see we are getting the result by making a Retrofit call and then we are pushing the result to callback.
For a detailed, step by step explanation go through this Android Paging Library Tutorial.