【问题标题】:RecyclerView ScrollListener inside NestedScrollViewNestedScrollView 内的 RecyclerView ScrollListener
【发布时间】:2017-02-15 03:04:07
【问题描述】:

我在NestedScrollView 的末尾有一个EndlessRecyclerViewEndlessRecyclerView 表示:当用户滚动到 recyclerView 的底部时,它会加载更多数据。这已经在其他地方实现和工作,但是当我将 recyclerView 放在 NestedScrollView 中时,OnScrollListener 事件不会触发。

XML 设计:

<NestedScrollView>

     <Other views/>

     <EndlessRecyclerView/>

</NestedScrollView >

代码:

recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            // This is never fired! Here is where I implement the logic of EndlessRecyclerView
        }
    });

如何获得上述情况的滚动事件?

我知道在彼此内部有两个可滚动视图是不好的。但是,如果没有两个可滚动的视图,我如何拥有上述情况?

我已经点击了这个链接,但它不起作用:scroll event for recyclerview inside scrollview android

【问题讨论】:

    标签: android android-recyclerview infinite-scroll onscrolllistener android-nestedscrollview


    【解决方案1】:

    要实现NestedScrollView下的recycler view无限滚动,可以使用“NestedScrollView.OnScrollChangeListener”

    nestedScrollView.setOnScrollChangeListener((NestedScrollView.OnScrollChangeListener) (v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
                if(v.getChildAt(v.getChildCount() - 1) != null) {
                    if ((scrollY >= (v.getChildAt(v.getChildCount() - 1).getMeasuredHeight() - v.getMeasuredHeight())) &&
                            scrollY > oldScrollY) {
                            //code to fetch more data for endless scrolling
                    }
                }
            });
    

    这里v.getChildCount() -1 应该为您提供要实现无限滚动的回收器视图。

    另外scrollY &gt; oldScrollY 确认页面正在向下滚动。

    参考:NestedScrollView.OnScrollChangeListener

    【讨论】:

    • 真棒人我花了一整天的时间认真解决它,你用两行来解决它。太好了……但是现在我怎样才能获得可见的项目和所有内容,以便我可以在服务器上获取新记录?
    • @RahulVats 在上面的代码中,当满足 if 条件时,意味着用户已经完全向下滚动并且最后一项可见。假设您有 100 个项目,最初加载了 20 个项目。如果满足上述条件,您可以从您的服务器下载下一组数据(例如:21-40)。无论如何,您可以参考此链接进行实际查询:stackoverflow.com/questions/40726438/…
    • 调用需要API级别23 我觉得如果RecyclerView上面的View不是太复杂的话,我们应该把它实现为RecyclerView的不同item类型,去掉NestedScrollView,它可以继续循环技术也。
    • @ThinkTwiceCodeOnce 它不需要 API 级别 23。它支持 API 14。您可以在此处阅读更多信息 - developer.android.com/reference/android/support/v4/widget/…
    • @ThinkTwiceCodeOnce 设置此侦听器时,应使用 NestedScrollView.OnScrollChangeListener(),而不是 View.OnScrollChangeListener()。
    【解决方案2】:
    nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener()
    {
        @Override
        public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY)
        {
           if (v.getChildAt(v.getChildCount() - 1) != null)
           {
              if (scrollY > oldScrollY)
              {
                 if (scrollY >= (v.getChildAt(v.getChildCount() - 1).getMeasuredHeight() - v.getMeasuredHeight()))
                 {
                    //code to fetch more data for endless scrolling
                 }
              }
           }
        }
     });
    

    【讨论】:

      【解决方案3】:

      我也遇到过类似的问题,虽然有点不同。在我的例子中,当 NestedScrollView 在 content_main xml(活动的一部分)中时,我在片段中有一个 recycleview。

      我用 SwipeRefreshLayout 包裹了我在片段中的回收视图

      这是我的片段的代码:

          <?xml version="1.0" encoding="utf-8"?>
      <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
          android:id="@+id/swipe_dummy"
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="wrap_content">
      
          <androidx.recyclerview.widget.RecyclerView
              android:id="@+id/top_series_recycle_view"
              android:layout_width="match_parent"
              android:layout_height="match_parent" />
      
      </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
      

      剩下要做的就是从代码中禁用 SwipeRefreshLayout

      mSwipeLayout.isEnabled = false
      

      如果您不这样做,当您向下滑动时,它将显示无限刷新图标。 我想分享这个解决方案,以防有人需要这个功能或者也有这个问题

      使用 SwipeRefreshLayout 包装回收视图后,您将看到 recycleview 的 addOnScrollListener 将照常调用

      【讨论】:

        【解决方案4】:
        nestedScrollView.setOnScrollChangeListener { v: NestedScrollView?, scrollX: Int, scrollY: Int, oldScrollX: Int, oldScrollY: Int ->
        
                val view = nestedScrollView.getChildAt(nestedScrollView.childCount - 1)
                Timber.d("Count==============${nestedScrollView.childCount}")
        
                val diff = view.bottom - (nestedScrollView.height + nestedScrollView.scrollY)
                Timber.d("diff==============$diff")
        
                if (diff == 0) {
                    //your api call to fetch data
                    page++
                    apiCall()
                }
        
        
            }
        

        【讨论】:

          猜你喜欢
          • 2017-05-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-03-21
          • 1970-01-01
          • 2015-03-05
          相关资源
          最近更新 更多