如何获取 RecyclerView 的滑动距离

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何获取 RecyclerView 的滑动距离相关的知识,希望对你有一定的参考价值。

参考技术A   1.利用OnScrollListener

  [java] view plain copy
  mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener()
  private int totalDy = 0;
  @Override
  public void onScrolled(RecyclerView recyclerView, int dx, int dy)
  totalDy -= dy;
  
  );
 
 如代码所述,totalDy的确保存了 RecyclerView 的滑动距离,但是当我向下滑动 RecyclerView ,之后插入/删除/移动
Item 的时候,totalDy 就变得不精确了;比如删除或者插入新的Item,那么totalDy就不能再回归到 0了。
  解决办法:
监听RecyclerView的addOnScrollListener后自己记录onScrolled的dy,同时给adapter加个
registerAdapterDataObserver,监听插入/删除/移动,自己加减前面记录的dy滚动值。自己没有试过,不知道是否可行!
  2. 有人说可以尝试computeVerticalScrollOffset()

  [java] view plain copy
  totalDy = recyclerView.computeVerticalScrollOffset();
  然而compute方法计算出的并不是滑动的精确距离,stackOverflow上有答案解释其为 item 的平均高度 * 可见 item 数目,不是我们需要的精确距离。
  3. 还有人说可以尝试getChildAt(0)

  [java] view plain copy
  totalDy = recyclerView.getChildAt(0).getTop();
  依靠第一个item的滑动距离来进行动画的设置,但是根据该方法得出的 totalDy 在滑动到一定程度后清零。
  这是因为recyclerViewl.getChildAt(0) 返回的永远是第一个可见的child,不是所有view list 的第一个child,因此这种用法是得不到滑动距离的。

  另外下面这三种用法都是等价的,都是获取第一个可见的child:

  [java] view plain copy
  LinearLayoutManager layoutManager = (LinearLayoutManager) this.getLayoutManager();
  View firstVisiableChildView = this.getChildAt(0);
  View firstVisiableChildView = layoutManager.getChildAt(0)
  int position = layoutManager.findFirstVisibleItemPosition();
  View firstVisiableChildView = layoutManager.getChildAt(position)
  但是下面这种就不是获取第一个可见的child,而是获得所有view list 的第一个child。但是滑动一段距离后它总是返回null,即第一个child被recycle后,总是返回null。
  [java] view plain copy
  //Don't use this function to get the first item, it will return null when the first item is recycled.
  LinearLayoutManager layoutManager = (LinearLayoutManager) this.getLayoutManager();
  View child2 = layoutManager.findViewByPosition(0);
  4.如果LayoutManager用的是LinearLayoutManager,强烈推荐下面的方法获取滑动距离:

  [java] view plain copy
  public int getScollYDistance()
  LinearLayoutManager layoutManager = (LinearLayoutManager) this.getLayoutManager();
  int position = layoutManager.findFirstVisibleItemPosition();
  View firstVisiableChildView = layoutManager.findViewByPosition(position);
  int itemHeight = firstVisiableChildView.getHeight();
  return (position) * itemHeight - firstVisiableChildView.getTop();
  

Android Recyclerview 监听滑动状态和滑动距离

计算滑动距离

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() 
            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) 
                super.onScrolled(recyclerView, dx, dy);
                Log.d(TAG,getScollYDistance()+"");
            
);
    public int getScollYDistance() 
        LinearLayoutManager layoutManager = (LinearLayoutManager) rvHomeHouse.getLayoutManager();
        int position = layoutManager.findFirstVisibleItemPosition();
        View firstVisiableChildView = layoutManager.findViewByPosition(position);
        int itemHeight = firstVisiableChildView.getHeight();
        return (position) * itemHeight - firstVisiableChildView.getTop();
    

监听滑动状态

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() 
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) 
                super.onScrollStateChanged(recyclerView, newState);
                switch (newState)
                    case RecyclerView.SCROLL_STATE_DRAGGING:
                        Log.d("wangrui","正在拖拽");
                        break;
                    case RecyclerView.SCROLL_STATE_IDLE:
                        Log.d("wangrui","滑动停止");
                        break;
                    case RecyclerView.SCROLL_STATE_SETTLING:
                        Log.d("wangrui","惯性滑动中");
                        break;
                
            
                        @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) 
                super.onScrolled(recyclerView, dx, dy);
                /*每次滑动必定调用这里*/
            

以上是关于如何获取 RecyclerView 的滑动距离的主要内容,如果未能解决你的问题,请参考以下文章

如何获取Android RecyclerView滑动的距离

Android教程2020 - RecyclerView获取滑动距离

Android RecyclerView 获取滑动距离

如何禁止recyclerview的滚动时间

Android Recyclerview 监听滑动状态和滑动距离

Android Recyclerview 监听滑动状态和滑动距离