如何使用分页库代替普通的适配器和recyclerview?

时间:2019-05-21 08:41:10

标签: android kotlin android-recyclerview

这将是最长的帖子,并且如果这个问题被关闭或投反对票,我不会感到生气,因为我自己无法解决此问题,并且需要专业程序员的帮助。

因此,每个人都知道诸如Facebook,Twitter或Gmail之类的应用程序。在每个这些应用程序中,我们都使用列表。我认为这些列表基于具有分页库的Recyclerview。我想在我的应用程序中创建类似的列表,但是我不知道该怎么做。

我现在所拥有的:

  1. 改装库-用于通过API从服务器获取数据(每条数据包含50个项目)
  2. 带有自定义适配器的RecyclerView
  3. 滚动侦听器,用于在列表到达recyclerView的底部或顶部时获取新数据。

我的方法用新数据重新创建了recyclerView,它看起来不是很好。我有几种创建无限列表的解决方案:

  1. 使用基于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)
            }
        })
    

此解决方案发送具有新偏移量的新请求:

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

它可以在顶部和底部发送请求,但是这种解决方案不够好。

  1. 另一种解决方案-Google的分页库。据我了解,我将不得不使用:PageKeyedDataSource,但我不知道如何使用它而不是当前版本。我看到了很多解决方案列表无穷无尽的问题,但是除了创建扩展了PageKeyedDataSource的类之外,我什么也没做。
  2. 另一个基于scrollListener的解决方案-将数据动态添加到适配器。这意味着我将向适配器发送新数据集,然后在recyclerView的最后一项之后添加新项。但我也看到,此方法还重绘了具有可见效果的recyclerview。也许我做错了。

现在在api调用之后,我得到了arrayList,然后将其发送到我的适配器:

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

因此,要从“页面”获取数据,我必须传递从响应中获得的下一个/上一个偏移号。因此,我该如何使用pageingAdapter或其他解决方案来帮助我无休止地列出我现在拥有的清单。

P.S。如果对正确答案很重要,我可以发布适配器。

1 个答案:

答案 0 :(得分:1)

我认为使用回收视图进行分页的最佳方法是在回收视图中使用EndlessScrollListener,您可以从以下链接中找到示例代码。

Example one

Example two