目录

Android嵌套滑动:NestedScrollingParent使用详解


  • 此接口应由希望支持嵌套子视图委派的滚动操作的ViewGroup子类实现。

  • 实现此接口的类应该创建NestedScrollingParentHelper的最终实例作为字段,并将任何View或ViewGroup方法委托给相同签名的NestedScrollingParentHelper方法。

  • 调用嵌套滚动功能的视图应始终从相关的ViewCompat,ViewGroupCompat或ViewParentCompat兼容性填充静态方法执行此操作。 这确保了与Android 5.0 Lollipop和更新版本上的嵌套滚动视图的互操作性。

方法
返回值 方法名 描述
abstract int getNestedScrollAxes() 返回此NestedScrollingParent的嵌套滚动的当前轴。返回除SCROLL_AXIS_NONE外的值,一般为SCROLL_AXIS_HORIZONTAL或SCROLL_AXIS_VERTICAL
abstract boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) 从嵌套滚动请求fling。该方法的调用表示嵌套滚动子View通过某些条件检测到了fling事件
abstract boolean onNestedPreFling(View target, float velocityX, float velocityY) 在目标视图消耗它之前对嵌套的fling做出反应。
abstract void onNestedPreScroll(View target, int dx, int dy, int[] consumed) 在嵌套滚动子View对滚动事件作出响应之前,通过该方法父View可以先行消费该滚动事件,对正在进行的嵌套滚动作出反应。
abstract void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) 对正在进行的嵌套滚动做出反应。当ViewParent的当前嵌套子View分发了嵌套滚动事件时该方法将被调用,只有在onStartNestedScroll(View, View, int).返回true时该方法才会被调用
abstract void onNestedScrollAccepted(View child, View target, int axes) 对成功处理嵌套滚动操作做出反应。该方法将在onStartNestedScroll返回true时被调用,它为视图及其超类提供了对嵌套滚动执行初始配置的机会,此方法的实现应始终调用其超类的此方法的实现
abstract boolean onStartNestedScroll(View child, View target, int axes) 对启动可嵌套滚动操作的后代视图做出反应,声明嵌套滚动操作(如果适用)
abstract void onStopNestedScroll(View target) 对嵌套滚动操作结束的反应。
图解
  • A:刚进入滚动状态时接收到child发来的通知
  • B:开始处理滚动

注解

  • 注解1:当child刚进入滚动状态时,会回调onStartNestedScroll,通常在该方法中我们根据一定的条件返回true或者false,true表示你需要接收嵌套滑动child的滑动数据,让child先不要动,放着让你来
  • 注解2:如果onStartNestedScroll返回true时,该方法接下来会被回调(为什么返回true时才被回调在上一篇分析NestedScrollingChild时已将分析了,不大清楚的小伙伴可以点击看一下)。在该方法中我们通常做一些处理滑动前的准备功能,如初始化一个变量等。
  • 注解3:嵌套child在处理滑动前为了遵从中华人名优良的文化传统-尊老爱幼,先把拿到的滑动量传递给嵌套parent,此时onNestedPreScroll被回调,在这里我们可以优先于child把滑动的偏移量消费掉,然后将消费了多少通过放入consumed中回传给child(int[]类型是地址引用)
  • 注解4:child在parent执行完接onNestedPreScroll里的代码后开始执行自己的操作,然后child是个相当不错的孩子,他还将自己消费了多少,还剩多少可以消费再次告知parent,此时parent的onNestedScroll函数被调用,一般在该方法中可以根据实际情况做一些操作
  • 注解5:在结束的时候,我们的好孩子child依然保持有始有终的做事理念告知我们的parent,我的滑动结束了,此时parent的onStopNestedScroll被调用,可以在这里做一些变量的重置工作
sequenceDiagram participant A participant B participant C A->>A:onStartNestedScroll(View child, View target, int axes)->注解1 A->>A:onNestedScrollAccepted(View child, View target, int axes)->注解2 A-->>B:child开始要处理滑动操作了 B->>B:onNestedPreScroll(View target, int dx, int dy, int[] consumed)->注解3 B->>B:onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed)->注解4 B-->>C:滑动进入结束阶段 C->>C:onStopNestedScroll->注解5
  • NestedScrollingParentHelper代码相对比较少,这里就不做讲解,感兴趣的可以看下

    public class NestedScrollingParentHelper {
        private final ViewGroup mViewGroup;
        private int mNestedScrollAxes;
    
        public NestedScrollingParentHelper(ViewGroup viewGroup) {
            this.mViewGroup = viewGroup;
        }
    
        public void onNestedScrollAccepted(View child, View target, int axes) {
            this.mNestedScrollAxes = axes;
        }
    
        public int getNestedScrollAxes() {
            return this.mNestedScrollAxes;
        }
    
        public void onStopNestedScroll(View target) {
            this.mNestedScrollAxes = 0;
        }
    }
    
总结
  • 至此,我们把嵌套滑动相关的知识点都梳理了以便,后续将通过实现一个支持CoordinatorLayout、嵌套滑动和传统滑动的刷新和加载控件来进行实战,