我使用下面的方法来检查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()
会调用两次或三次。
您可以看到我正在管理一个布尔变量isLoadMore
这里,我过1。第页,2。调用我的Web服务时限制。
默认情况下,页面为1,限制为20。下一次将是2(第页(和20(限制(。
因此,每次web服务调用获取20个数据。
现在,如果作为响应,我发现新的数据大小小于我的限制,我将执行isLoadMore为false。
问题可能是什么?你能指导我解决这个问题吗。我怎么能完全知道这是当回收站到达终点时呼叫服务的时候。
谢谢。
将其指示的
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
}
有一个专门的库为recyclerView提供分页。查看分页库。您将需要实现PageKeyedDataSource<Int, Item>()
,在那里您可以调用您的apiCall()
。有一个很好的教程来实现分页库的改装调用
最后,我完成了以下操作:
采取了一种变体:
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
}
}
选中,在滚动:中
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()
}
}
}