简体   繁体   English

Kotlin - Recyclerview 分页问题

[英]Kotlin - Issue in Recyclerview Pagination

I am using below method to check that Recyclerview is reached up to bottom or not..ie last position in the Recyclerview is visible or not :我正在使用下面的方法来检查 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()
                }
            }
        }
    })

The Issue is apiCall() is calling twise or thrise sometime when I scrolls the Recyclerview to the bottom .问题是apiCall()有时在我将 Recyclerview 滚动到底部时调用 twise 或 thrise

You can see I am managing a boolean variable isLoadMore你可以看到我正在管理一个布尔变量isLoadMore

Here, I am passing 1. Page, 2. Limit while calling my webservice.在这里,我在调用我的网络服务时传递 1. Page,2. Limit。

by default page is 1 and limit is 20. Next time it will be 2(page) and 20(limit).默认页面为 1,限制为 20。下次它将是 2(页)和 20(限制)。

So, fetching 20 data per web service call.因此,每次 Web 服务调用获取 20 个数据。

Now, if in response I found that newly data size is less than my limit, am doing is isLoadMore to false.现在,如果作为回应我发现新的数据大小小于我的限制,我正在做的是isLoadMore为 false。

What might be the Issue ?可能是什么问题? Can you please guide me to resolve this issue.你能指导我解决这个问题吗? How can I perfectly know that This is the time to call service when recyclerview reached to end.我怎么能完全知道这是当 recyclerview 到达结束时调用服务的时间。

Thanks.谢谢。

Add isLoading boolean value it indicates to apiCall() in progress.添加isLoading布尔值,它指示apiCall()

Ex)前任)

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
}

There is a dedicated library that provides paginations to the recyclerView.有一个专门的库为 recyclerView 提供分页。 Check out Paging Library .查看分页库 You will need to implement PageKeyedDataSource<Int, Item>() where you can call your apiCall() .您将需要实现PageKeyedDataSource<Int, Item>() ,您可以在其中调用apiCall() There is a great tutorial to implement Retrofit calls with Paging library有一个很棒的教程可以使用 Paging 库实现 Retrofit 调用

Finally, I have done as below :最后,我做了如下:

Taken a varibale :取一个变量:

private var isScrolling = true

Inside, OnScrollStateChanged :在里面, OnScrollStateChanged :

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

Checked It, in onScrolled :检查它,在 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()
                }
            }
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM