Android 嵌套滑動詳解

參考:
Android嵌套滑動講解簡書:https://www.jianshu.com/p/f4763bf8f9ba

方法總結

startNestedScroll : 起始方法, 主要作用是找到接收滑動距離信息的外控件.

dispatchNestedPreScroll : 在內控件處理滑動前把滑動信息分發給外控件.

dispatchNestedScroll : 在內控件處理完滑動後把剩下的滑動距離信息分發給外控件.

stopNestedScroll : 結束方法, 主要作用就是清空嵌套滑動的相關狀態

setNestedScrollingEnabled和isNestedScrollingEnabled : 一對get&set方法, 用來判斷控件是否支持嵌套滑動.

dispatchNestedPreFling和dispatchNestedFling : 跟Scroll的對應方法作用類似NestedScrollingParent

onStartNestedScroll : 對應startNestedScroll, 內控件通過調用外控件的這個方法來確定外控件是否接收滑動信息.

onNestedScrollAccepted : 當外控件確定接收滑動信息後該方法被回調, 可以讓外控件針對嵌套滑動做一些前期工作.

onNestedPreScroll : 關鍵方法, 接收內控件處理滑動前的滑動距離信息, 在這裏外控件可以優先響應滑動操作, 消耗部分或者全部滑動距離.

onNestedScroll : 關鍵方法, 接收內控件處理完滑動後的滑動距離信息, 在這裏外控件可以選擇是否處理剩餘的滑動距離.

onStopNestedScroll : 對應stopNestedScroll, 用來做一些收尾工作.

onNestedPreFling和onNestedFling : 同上略

嵌套滑動事件傳遞過程

在這裏插入圖片描述

  • NestedScrollingParent2
    給嵌套滑動的父View使用的,它的方法是用來接收嵌套滑動子View的通知。用法還是容易理解核心邏輯就是在子View消費之前與之後,向父View發出通知,看看父View是否對這此有何處理,然後再將結果返還給子View。

  • NestedScrollingChild2
    給嵌套滑動的子View使用的,它的方法是用來給嵌套滑動父View的發送通知。用法也很容易理解,核心邏輯就是在子View消費之前,向父View發出通知,看看父View是否對這此有何處理,然後再將結果返還給子View。

嵌套滑動抽象化:

在這裏插入圖片描述

  • NestedScrollingChildHelper
    代理類,嵌套滑動子控件都是通過這個幫助類來向它的父控件來傳遞通知的。
    這麼做的目的是爲了解耦合!!!
    嵌套滑動子View擁有!!!

  • NestedScrollingParentHelper
    代理類,嵌套滑動父控件都是通過這個幫助類存在一些通用的數據。
    這麼做的目的是爲了解耦合!!!
    嵌套滑動父View擁有!!!

public interface NestedScrollingParent2 extends NestedScrollingParent {
    /**
     * 這個是嵌套滑動控制事件分發的控制方法,只有返回true才能接收到事件分發
     * @param child 包含target的ViewParent的直接子View
     * @param target 發起滑動事件的View
     * @param axes 滑動的方向,數值和水平方向{@link ViewCompat#SCROLL_AXIS_HORIZONTAL},
     *                         {@link ViewCompat#SCROLL_AXIS_VERTICAL} 
     * @return true 表示父View接受嵌套滑動監聽,否則不接受
     */
    boolean onStartNestedScroll(@NonNull View child, @NonNull View target, @ScrollAxis int axes,@NestedScrollType int type);

    /**
     * 這個方法在onStartNestedScroll返回true之後在正式滑動之前回調
     * @param child 包含target的父View的直接子View
     * @param target 發起嵌套滑動的View
     * @param axes 滑動的方向,數值和水平方向{@link ViewCompat#SCROLL_AXIS_HORIZONTAL},
     *                         {@link ViewCompat#SCROLL_AXIS_VERTICAL} or both
     */
    void onNestedScrollAccepted(@NonNull View child, @NonNull View target, @ScrollAxis int axes,@NestedScrollType int type);

    /**
     *
     * @param target View that initiated the nested scroll
     */
    void onStopNestedScroll(@NonNull View target);

    /**
     * 在子View滑動過程中會分發這個嵌套滑動的方法,要想這裏收到嵌套滑動事件必須在onStartNestedScroll返回true
     * @param dxConsumed 子View在水平方向已經消耗的距離
     * @param dyConsumed 子View在垂直方法已經消耗的距離
     * @param dxUnconsumed 子View在水平方向剩下的未消耗的距離
     * @param dyUnconsumed 子View在垂直方法剩下的未消耗的距離
     * @param type 發起嵌套事件的類型 分爲觸摸(ViewParent.TYPE_TOUCH)和非觸摸(ViewParent.TYPE_NON_TOUCH)
     */
    void onNestedScroll(@NonNull View target, int dxConsumed, int dyConsumed,
            int dxUnconsumed, int dyUnconsumed, @NestedScrollType int type);

    /**
     * 在子View開始滑動之前讓父View有機會先進行滑動處理
     * @param dx 水平方向將要滑動的距離
     * @param dy 豎直方向將要滑動的距離
     * @param consumed Output. 父View在水平和垂直方向要消費的距離,consumed[0]表示水平方向的消耗,consumed[1]表示垂直方向的消耗,
     */
    void onNestedPreScroll(@NonNull View target, int dx, int dy, @NonNull int[] consumed,
            @NestedScrollType int type);

}




public interface NestedScrollingChild2 extends NestedScrollingChild {

    //返回值true表示找到了嵌套交互的ViewParent,type表示引起滑動事件的類型,這個事件和parent中的onStartNestedScroll是對應的
    boolean startNestedScroll(@ScrollAxis int axes, @NestedScrollType int type);

    
    //停止嵌套滑動的回調
    void stopNestedScroll(@NestedScrollType int type);

    //表示有實現了NestedScrollingParent2接口的父類
    boolean hasNestedScrollingParent(@NestedScrollType int type);

    //分發嵌套滑動事件的過程
    boolean dispatchNestedScroll(int dxConsumed, int dyConsumed,
            int dxUnconsumed, int dyUnconsumed, @Nullable int[] offsetInWindow,
            @NestedScrollType int type);

    //在嵌套滑動之前分發事件
    boolean dispatchNestedPreScroll(int dx, int dy, @Nullable int[] consumed,
            @Nullable int[] offsetInWindow, @NestedScrollType int type);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章