【问题标题】:Kotlin - Issue in Recyclerview PaginationKotlin - Recyclerview 分页中的问题
【发布时间】:2020-06-12 09:02:54
【问题描述】:

我正在使用下面的方法来检查 Recyclerview 是否到达底部......即Recyclerview 中的最后一个位置是否可见:

recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {

        override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
            super.onScrollStateChanged(recyclerView, newState)
        }

        override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
            if (dy > 0) {
                visibleItemCount = recyclerView.getLayoutManager()!!.getChildCount()
                totalItemCount = recyclerView.getLayoutManager()!!.getItemCount()
                pastVisiblesItems =
                    (recyclerView.getLayoutManager() as GridLayoutManager).findFirstVisibleItemPosition()

                if (visibleItemCount + pastVisiblesItems >= totalItemCount && isLoadMore) {
                    // mocking network delay for API call
                    apiCall()
                }
            }
        }
    })

问题是当我将 Recyclerview 滚动到底部时,apiCall() 正在调用 twise 或 thrise。

你可以看到我正在管理一个布尔变量isLoadMore

在这里,我在调用我的网络服务时传递 1. 页面,2. 限制。

默认page是1,limit是20。下次会是2(page)和20(limit)。

因此,每次 Web 服务调用获取 20 个数据。

现在,如果在响应中我发现新的数据大小小于我的限制,我正在做的是将 isLoadMore 设置为 false。

可能是什么问题?你能指导我解决这个问题吗? 我怎么能完全知道这是recyclerview结束时调用服务的时间。

谢谢。

【问题讨论】:

  • 您应该添加boolean 值,如isLoading 以防止api重复调用。
  • 即您是在谈论添加 isScrolling 吗?

标签: android kotlin android-recyclerview scroll pagination


【解决方案1】:

将isLoading 布尔值添加到apiCall() 正在进行中。

前)

override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
            if (dy > 0) {
                visibleItemCount = recyclerView.getLayoutManager()!!.getChildCount()
                totalItemCount = recyclerView.getLayoutManager()!!.getItemCount()
                pastVisiblesItems =
                    (recyclerView.getLayoutManager() as GridLayoutManager).findFirstVisibleItemPosition()

                if (!isLoading && visibleItemCount + pastVisiblesItems >= totalItemCount && isLoadMore) {
                    // mocking network delay for API call
                    isLoading = true
                    apiCall()
                }
            }
        }

fun apiCall() {
    ...
    //when finished api request such as onResponse, onFailure function
    isLoading = false
}

【讨论】:

    【解决方案2】:

    有一个专门的库为 recyclerView 提供分页。查看Paging Library。您将需要实现PageKeyedDataSource<Int, Item>(),您可以在其中调用您的apiCall()。有一个great tutorial 可以使用 Paging 库实现 Retrofit 调用

    【讨论】:

      【解决方案3】:

      最后,我做了如下:

      取了一个变量:

      private var isScrolling = true
      

      在里面,OnScrollStateChanged:

        override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
        super.onScrollStateChanged(recyclerView, newState)
        if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
               isScrolling = true
           }
        }
      

      检查它,在 onScrolled 中:

      override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                  if (dy > 0) {
                      visibleItemCount = recyclerView.getLayoutManager()!!.getChildCount()
                      totalItemCount = recyclerView.getLayoutManager()!!.getItemCount()
                      pastVisiblesItems =
                          (recyclerView.getLayoutManager() as GridLayoutManager).findFirstVisibleItemPosition()
      
                      if (isScrolling && visibleItemCount + pastVisiblesItems >= totalItemCount && isLoadMore) {
                          isScrolling = false
                          // mocking network delay for API call
                         apiCall()
                      }
                  }
              }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-15
        • 2021-10-13
        • 1970-01-01
        • 2018-12-25
        • 1970-01-01
        • 2020-04-01
        • 2018-10-29
        相关资源
        最近更新 更多