【问题标题】:Recyclerview onscrolllistener not working when setNestedScrollingEnabled to false当 setNestedScrollingEnabled 为 false 时,Recyclerview onscrolllistener 不起作用
【发布时间】:2016-11-05 21:33:48
【问题描述】:

我想用recyclerView 实现分页,为此我将addOnScrollListener 添加到recyclerView,但是当我设置rvGridExplore.setNestedScrollingEnabled(false); 时,RecyclerView.OnScrollListener 无法正常工作

但是当我删除 rvGridExplore.setNestedScrollingEnabled(false); 它工作正常, 我不知道如何处理。

代码如下:

rvGridExplore = (RecyclerView) view.findViewById(R.id.rvGridExplore);
        final GridLayoutManager glm = new GridLayoutManager(context,2);
       // rvGridExplore.setNestedScrollingEnabled(false);
        rvGridExplore.setLayoutManager(glm);

       // final int visibleItemCount,totalCount,pastVisibleItems;
        rvGridExplore.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                Log.v("scrollll","state changed");
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if (dy > 0) {
                    int totalCount = glm.getItemCount();
                    int visibleItemCount = glm.getChildCount();
                    int pastVisibleItems = glm.findFirstVisibleItemPosition();
                    if (loading) {
                        if ((visibleItemCount + pastVisibleItems) >= totalCount) {
                            Log.v("scroll","scrolled"+pastVisibleItems);
                        }
                    }

                }
            }
        });

【问题讨论】:

  • 为什么需要调用 setNestedScrollingEnabled(false)?
  • 它位于协调器布局下的 NestedScrollView 下,如果我删除它,工具栏不会向上滚动
  • 等等,你想让工具栏向上滚动还是不向上滚动?
  • 我想向上滚动,当 rvGridExplore.setNestedScrollingEnabled(false); 时找到它的工作;
  • 这没有意义……应该是相反的。

标签: android android-recyclerview android-nestedscrollview


【解决方案1】:

这个问题可能很老,但为了帮助其他偶然发现这个问题的人,我想分享我所做的。我必须实现 onScroll Listener 到 recyclerview 以从服务器加载数据并进行一些 UI 更改。并且还需要 swipeRefresh Layout 来刷新数据。

这是我的 xml 文件结构,

-RelativeLayout

 -SwipeRefreshLayout

  -NestedScrollView

   -LinearLayout(Vertical)

    -Multiple views required

之后,为了检测上下滚动,我在 NestedScrollView 中实现了 setOnScrollListener。

正常使用 SwipeRefreshLayout 刷新数据。

为了加载更多数据,我在 NestedScrollingView 的 onScrollListener 内部实现了逻辑。

if (scrollY == (v.getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight()))  {

    // Load More Data
}

【讨论】:

    【解决方案2】:

    将 setOnScrollChangeListner 添加到您的 NestedScrollView

     nestedScrollview.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
            @Override
            public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                if (scrollY == (v.getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight()))  {
                   if(loading)
                    onClick();
                   loading=false;
                }
            }
        });
    

    从服务器加载数据后设置 boolean loading=true。

    【讨论】:

      【解决方案3】:

      如果你将recyclerView嵌入到任何NestedScrollView中,那么你应该将onScrollListener附加到NestedScrollView。

      这行得通!

      if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
          final GridLayoutManager gridLayoutManager = (GridLayoutManager) recyclerView.getLayoutManager();
          nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
              @Override
              public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                  if (scrollY == (v.getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight()))  {
                      totalItemCount = gridLayoutManager.getItemCount();
                      lastVisibleItem = gridLayoutManager.findLastVisibleItemPosition();
                      if (!loading
                              && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
                          // End has been reached
                          // Do something
                          if (onLoadMoreListener != null) {
                              onLoadMoreListener.onLoadMore();
                          }
                          loading = true;
                      }
                  }
              }
          });
      }
      

      【讨论】:

        【解决方案4】:

        您在对您的问题的评论中说“
        它位于协调器布局下的 NestedScrollView 下,如果我删除它,工具栏不会向上滚动”。这是一个错误

        我发现你不能同时拥有它,当你在 NestedScrollView 中添加了 RecyclerView 时,CoordinatorLayout 行为就会中断。您需要使用其中一个。

        当您在NestedScrollView 中有一个RecyclerView 时,只要您设置了RecyclerView.setNestedScrollingEnabled(false),它就可以工作,但是您发现这意味着不会调用OnScrollListener

        所有组件正常工作的唯一方法是删除NestedScrollView,确保不要将嵌套滚动设置为false并从那里开始工作。否则RecyclerView.OnScrollListener 事件将无法正确触发。

        【讨论】:

          【解决方案5】:

          第 1 步:创建 EndlessRecyclerOnScrollListener

          public abstract class EndlessRecyclerOnScrollListener extends RecyclerView.OnScrollListener {
          
              public static String TAG = EndlessRecyclerOnScrollListener.class.getSimpleName();
          
              // use your LayoutManager instead
              private LinearLayoutManager llm;
          
              public EndlessRecyclerOnScrollListener(LinearLayoutManager sglm) {
                  this.llm = llm;
              }
          
              @Override
              public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                  super.onScrolled(recyclerView, dx, dy);
          
                  if (!recyclerView.canScrollVertically(1)) {
                      onScrolledToEnd();
                  }
              }
          
              public abstract void onScrolledToEnd();
          }
          

          第 2 步:将滚动侦听器应用于回收站视图。

          recyclerview.addOnScrollListener(new EndlessRecyclerOnScrollListener(mLayoutManager) {
                      @Override
                      public void onScrolledToEnd() {
                          Log.e("Position", "Last item reached");
                          if (loadMore == true) {
                              // put your Load more code
                              // add 10 by 10 to tempList then notify changing in data
                          }
                      }
                  });
          

          【讨论】:

          • 你的意思是我把子类放在构造函数中它会工作吗?请正确阅读问题。由于 setNestedScrollingEnabled(false); 我的 Listener 无法正常工作
          • 为什么要放置 nestedScrollingEnabled(false) ??
          • 查看有关问题的 cmets
          • 我也用这段代码分页,就像你的情况一样
          • 如果您想要正确的答案,请先放置您的 layout.xml!
          【解决方案6】:

          删除嵌套滚动视图使用线性或相对布局而不是将其作为根元素,然后您可以编写 recyclerview.setNestedScrollEnabled(false);

          【讨论】:

            猜你喜欢
            • 2021-04-16
            • 2013-10-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-06-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多