Kotlin - Recyclerview 分页中的问题

Posted

技术标签:

【中文标题】Kotlin - Recyclerview 分页中的问题【英文标题】:Kotlin - Issue in Recyclerview Pagination 【发布时间】: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 吗? 【参考方案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()
                
            
        

【讨论】:

以上是关于Kotlin - Recyclerview 分页中的问题的主要内容,如果未能解决你的问题,请参考以下文章

kotlin Recycler查看分页

提供Kotlin阵列的补偿 .take(n:Int)。这是分页的好方法吗?

UIScrollview 分页中的 UITextview

Kotlin、RecyclerView、ViewBinding

如何使分页中的“无”字消失?

Android Studio(Kotlin)之RecyclerView