Andrew
Andrew

Reputation: 2157

How to use Paging library instead of ordinary adapter and recyclerview?

It will be the longest post and I won't be angry if this question will be closed or down voted, because I can't solve this problem by myself and I need some help of professional programmers.

So, everybody knows such apps like Facebook, Twitter or Gmail. At each of these apps we use lists. I think that these lists are based on Recyclerview with paging library. I would like to create similar list at my app but I don't know how I can do it.

What I have right now:

  1. Retrofit library - for getting data from server via API (each piece of data contains 50 items)
  2. RecyclerView with custom adapter
  3. Scroll listener which is used for getting new data when list reaches the bottom or the top of the recyclerView.

My method recreate recyclerView with new data and it looks not very good. I have several solutions for creating endless list:

  1. Stay with current solution which is based on scrollListener:

     msgLst.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                val visibleItemCount = mLayoutManager.childCount
                val totalItemCount = mLayoutManager.itemCount
                val pastVisibleItems = mLayoutManager.findFirstVisibleItemPosition()
    
                if (loading) {
                    if (visibleItemCount + pastVisibleItems >= totalItemCount /*&& !recyclerView.canScrollVertically(1)*/) {
                        if (nextUrl != null) {
                            if (sp.getLong("expires_in", 0) - sp.getLong("time_delta", 0) - System.currentTimeMillis() / 1000 <= 60) {
                                error["message"] = "access_token_expired"
                                error["request_no"] = "7"
                                Singleton.workingWithErrors(error, context!!)
                            } else {
                                getMessages(type, Integer.parseInt(Uri.parse(nextUrl).getQueryParameter("offset")), true)
                            }
                        }
                    }
                }
                if (dy >= 30) {
                    loading = true
                }
                if (dy < 0) {
                    if (loading) {
                        if (mLayoutManager.findFirstVisibleItemPosition() - mLayoutManager.childCount <= 0 /*&& !recyclerView.canScrollVertically(-1)*/) {
                            loading = false
    
                            if (prevUrl != null) {
                                if (sp.getLong("expires_in", 0) - sp.getLong("time_delta", 0) - System.currentTimeMillis() / 1000 <= 60) {
                                    error["message"] = "access_token_expired"
                                    error["request_no"] = "7"
                                    Singleton.workingWithErrors(error, context!!)
                                } else {
                                    Singleton.m_offset = Integer.valueOf(Uri.parse(prevUrl).getQueryParameter("offset"))
                                    getMessages(type, Integer.parseInt(Uri.parse(prevUrl).getQueryParameter("offset")), true)
                                }
                            }
                        }
                    }
                }
    
                super.onScrolled(recyclerView, dx, dy)
            }
        })
    

this solution send a new request with new offset:

Integer.parseInt(Uri.parse(prevUrl).getQueryParameter("offset")

it can send request at the top and at the bottom but this solution is not good enough.

  1. Another solution - paging library from Google. As I understood I will have to use: PageKeyedDataSource but I can't understand how to use it instead of my current variant. I saw a lot of solutions with endless list but I couldn't make anything except creating class which extends PageKeyedDataSource and then I didn't know what to do.
  2. One more solution which is based on scrollListener - dynamically adding data to adapter. It means that I will send new data set to adapter and then will add new items after the last item of recyclerView. But I also see that this method also redraws recyclerview with visible effects. Maybe I did smth wrong.

Right now after api call I'm getting arrayList and then send it to my adapter:

val messageArrayList = response.body()!!.messages
adapter = MessageListAdapter((messageArrayList as ArrayList<MessageModel>), context!!, type)
adapter.notifyDataSetChanged()
msgLst.adapter = adapter

So for getting data from the "page" I have to pass next/previous offset number which I get from response. So how I can use pagingAdapter or another solution which will help me to make endless list instead what I have right now.

P.S. I can post my adapter if it will be important for giving a right answer.

Upvotes: 1

Views: 1778

Answers (1)

Dulanga
Dulanga

Reputation: 931

I think best way to do pagination with recycle view is use EndlessScrollListener with your recycle view you can find example code from below links.

Example one

Example two

Upvotes: 1

Related Questions