How does Android Paging Library know to load more data?
Asked Answered
D

1

21

Iʼm fairly new to developing Android apps and Iʼm trying to do everything “the right way.” So right now, Iʼm implementing the new Android Paging Library into my project, where I need to load a list of articles from a network server.

I have an ArticlesRepository class that returns an ArticleList class containing instances of ArticleListItem that I would like to display in a RecyclerView. The list of articles is paginated already on the server, so the repository sends a request for the first page and returns an ArticleList with the page property set to 1 and the articles property containing a List<ArticleListItem> of articles on the requested page. I donʼt know how many articles can be on one page.

Now, I was able to implement a PageKeyedDataSource<Integer, ArticleListItem>, but it only fetches the first page:

@Override
public void loadInitial(@NonNull LoadInitialParams<Integer> params, @NonNull LoadInitialCallback<Integer, ArticleListItem> callback) {
    ArticleList list = load(1);
    if (list != null) {
        callback.onResult(list.articles, null, next(list));
    }
}

@Override
public void loadBefore(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, ArticleListItem> callback) {
    ArticleList list = load(previous(params.key));
    if (list != null) {
        callback.onResult(list.articles, previous(list));
    }
}

@Override
public void loadAfter(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, ArticleListItem> callback) {
    ArticleList list = load(next(params.key));
    if (list != null) {
        callback.onResult(list.articles, next(list));
    }
}

The previous/next functions return an Integer with the previous/next page number or null if there isnʼt one.

In my ViewModel, I configure the PagedList like this:

PagedList.Config config = new PagedList.Config.Builder()
            .setEnablePlaceholders(false)
            .setInitialLoadSizeHint(1)
            .setPageSize(1)
            .setPrefetchDistance(1)
            .build();

This way Iʼm able to load the first page, but when I scroll to the bottom of the RecyclerView (that is inside a NestedScrollView), nothing happens. Debugging shows that the PageKeyedDataSource.loadAfter method is not invoked.

Do I have to somehow tell the PagedList that the next page has to be loaded, or is it the RecyclerView/DataSource/GodKnowsWhatElseʼs job and Iʼm just doing something wrong? Thanks for any advice.

Dreyer answered 5/7, 2018 at 18:24 Comment(1)
I gave a new good solution in this answer: https://mcmap.net/q/660200/-use-pagedlistadapter-inside-nestedscrollview TLDR; You have to use 'MergeAdapter' that recently added to RecyclerviewPerionychium
F
31

The paging library should know automatically when to load new items. The problem in your implementation is that the paged RecyclerView is inside a NestedScrollView and according to this issue the libary doesn't have built in support for that.

when you put recyclerview inside an infinite scrolling parent, it will layout all of its children because the parent provides infinite dimensions.

You'll need to create your own implementation of Nested Scroll View, there is actually one here in this gist that might be able to help you.

It is also suggested to add fillViewPort to this custom nested scroll view:

android:fillViewport="true" to scrollable container

Fimble answered 5/7, 2018 at 18:47 Comment(6)
Thank you, this was the cause indeed. Instead of implementing my own Nested Scroll View, I removed it altogether and put the other views from the Scroll View inside the Recycler View, fixing this issue and improving performance.Dreyer
Yes It will be nice to have solution like in iOS TableView inside ScrollView, where there is scrolling of parent scrollview and then scrolling of inner tableview idependently. And Tableview fill entire screen if scrolled to fill screen.Halfback
every day i question why i'm an android developer , then stackoverflow change my mind , thank you , this works !Tswana
But suppose I have one view and a recycler view inside this SmartNestedScrollView, only the recycler view is scrollable. How can I fix this?Thorncombe
Thanks , glad to know what caused pagination library to load all the pages from the serverRadioactive
Also have a look at this question https://mcmap.net/q/660201/-implmenent-paging-library-3-0-filter-search-functionality/3496570Eusebioeusebius

© 2022 - 2024 — McMap. All rights reserved.