Search code examples
androidandroid-recyclerviewandroid-libraryandroid-loadermanagerandroid-loader

How to implement a paging mechanism into a RecyclerView with a potentially big data source?


I am looking for a good way to implement a paging mechanism into my RecyclerView lists. I'm using an AsyncTaskLoader to populate and cache the data into the RecyclerView.

public class HeadlinesListLoader extends AsyncTaskLoader<List<Headline>> {

    public HeadlinesListLoader(Context context) {
        super(context);
    }

    @Override
    protected void onStartLoading() {
        forceLoad();
    }

    @Override
    public List<Headline> loadInBackground() {
        return DataManager.getInstance().findAllHealines();
    }

    @Override
    public void deliverResult(List<Headline> data) {
        super.deliverResult(data);
    }
} 

Where DataManager.getInstance().findAllHealines(); makes the RESTful call to retrieve the list data, however, it's currently loading all the data at once which might take significantly long.

I've been looking into an efficient way to gradually load the data into the RecyclerView as needed. I came across this Paging Library recommended by Android:

https://developer.android.com/topic/libraries/architecture/paging.html

However, the way it's querying the database in the front-end doesn't sound like the right solution in my case and since I'm using AsyncTaskLoader, I'm wondering if there is a way to solve this problem using the Loaders framework itself? Or what would be a better option?

I'm open to any suggestions. Thanks.


Solution

  • You can do this on scroll event.

    YourListElement.addOnScrollListener(new RecyclerView.OnScrollListener() {
            boolean isSlidingToLast = false;
            int lastVisibleItemPosition = 0;
            int lastPositions = 0;
    
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                if (newState == RecyclerView.SCROLL_STATE_IDLE && linearLayoutManager.getItemCount() > 0) {
                    lastPositions = linearLayoutManager.getItemCount();
                    lastVisibleItemPosition = linearLayoutManager.findLastVisibleItemPosition();
    
                    if (lastPositions - 1 == lastVisibleItemPosition && isSlidingToLast) {
                        loadData(false);
                    }
                }
            }
    
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                isSlidingToLast = dy > 0;
            }
        });
    

    load data is the function that get the new data to populate