嵌套滑動 - Behavior

CoordinatorLayout
類似于一個FrameLayout 的容器,在嵌套滑動中有兩個功能:
1.作為嵌套滑動頂層布局
2.作為與一個或者多個直接子view進(jìn)行交互的特定容器

通過給 CoordinatorLayout 的直接子view設(shè)置 Behaviors 屬性猿涨,實(shí)現(xiàn)子view之間進(jìn)行不同的滑動交互以及布局修改姆怪。實(shí)現(xiàn)子view之間執(zhí)行移動或者動畫的澡绩,實(shí)現(xiàn)其他子View跟隨動作俺附。

Behavior
這個CoordinatorLayout類內(nèi)部的 抽象類,定義了子試圖的交互行為召调。這些互動可能包括拖曳蛮浑,滑動,投擲艺沼,或任何其他手勢蕴掏。主要的Api如下:
CoordinatorLayout.Behavior

/**
     * 是否給應(yīng)用了Behavior的View,指定一個觀察的布局
     * 當(dāng)布局發(fā)生變化的時候
     * 確定所提供的子視圖是否有另一個特定的同級視圖作為布局依賴項(xiàng)。
     * 注意:本身的View會重新布局
     *
     * @param parent 頂層嵌套布局
     * @param child 綁定behavior的View(觀察者,就是TextView本身)
     * @param dependency 被觀察的view(被觀察者挽荡,就是同級別的其他子視圖)
     * @return 這里可以檢查自己需要觀察的試圖即供,是返回true,否則返回false
     */
    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
        Log.i(TAG,"layoutDependsOn child " + child.getClass().getSimpleName()
                + "  dependency " + dependency.getClass().getSimpleName());
        // 這里檢查被觀察者(TexView觀察的是滑動NestedScrollView)
        return dependency instanceof NestedScrollView;
    }


    /**
     * 是否響應(yīng)子程序依賴視圖(被觀察者)中的更改
     * 每當(dāng)依賴視圖在標(biāo)準(zhǔn)布局流之外的大小或位置發(fā)生變化時青自,都會調(diào)用此方法
     *
     * @param parent 頂層嵌套布局
     * @param child 綁定behavior的View(觀察者,就是TextView本身)
     * @param dependency 被觀察的view(被觀察者驱证,就是同級別的其他子視圖)
     * @return true 響應(yīng)了被觀察者的變化,false沒有響應(yīng)
     */
    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
        Log.i(TAG,"onDependentViewChanged child " + child.getClass().getSimpleName()
                + "  dependency " + dependency.getClass().getSimpleName());
        //一開始  等于0
        if (deltaY == 0) {
            //初始化兩者之間的距離
            deltaY = dependency.getY() - child.getHeight();
        }
        Log.i("DN deltaY------------>",deltaY+"------------");
        //被觀察者View的Y坐標(biāo) - 觀察者的高度  得到兩者之間剩余的距離
        float dy = dependency.getY() - child.getHeight();
        //如果距離小于0  就賦值0  如果距離大于等于0  就把剩余距離賦值給它
        dy = dy < 0 ? 0 : dy;
        //計(jì)算Y軸每次偏移的距離
        float y = -(dy / deltaY) * child.getHeight();
        Log.i("DN-------------->",y+"------------");
        //設(shè)置Y軸的偏移參數(shù)
        child.setTranslationY(y);
        return false;
    }

    /**
     *  當(dāng)coordinatorLayout 的子View試圖開始嵌套滑動的時候被調(diào)用
     *  任何與協(xié)調(diào)員Layout的任何直接子級相關(guān)聯(lián)的行為都可能響應(yīng)此事件并返回TRUE,
     *  以指示協(xié)調(diào)員Layout應(yīng)該充當(dāng)此滾動條的嵌套滾動父級伙单。
     *  只有從此方法返回true的行為才會接收后續(xù)嵌套滾動事件车份。
     *
     * @param coordinatorLayout 頂層嵌套布局
     * @param child 綁定behavior的View(觀察者,就是TextView本身)
     * @param directTargetChild 該子視圖是或包含嵌套滾動操作的目標(biāo)
     * @param target View啟動嵌套滾動的協(xié)調(diào)員Layout的后代視圖
     * @param nestedScrollAxes 嵌套滑動滑動方向,橫向或者豎向
     * @param type 導(dǎo)致此滾動事件的輸入類型
     * @return 如果行為希望接受此嵌套滾動扫沼,則為true。
     */
    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild,
                                       View target, int nestedScrollAxes, int type) {
        Log.i(TAG,"onStartNestedScroll type " + type);
        return true;
    }


    /**
     * 當(dāng)正在進(jìn)行的嵌套滾動即將更新時严就,在目標(biāo)消耗任何滾動距離之前調(diào)用
     * 在nested scroll child 消費(fèi)掉自己的滾動距離之前梢为,嵌套滾動每次被nested scroll child
     * 更新都會調(diào)用onNestedPreScroll。注意有個重要的參數(shù)consumed铸董,可以修改這個數(shù)組表示你消費(fèi)
     * 了多少距離粟害。假設(shè)用戶滑動了100px,child 做了90px 的位移,你需要把 consumed[1]的值改成90悲幅,
     * 這樣coordinatorLayout就能知道只處理剩下的10px的滾動。
     *
     * @param coordinatorLayout 頂層嵌套布局
     * @param child 綁定behavior的View(觀察者,就是TextView本身)
     * @param target View啟動嵌套滾動的協(xié)調(diào)員Layout的后代視圖
     * @param dx  用戶試圖滾動的原始水平像素?cái)?shù)
     * @param dy  用戶試圖滾動的原始垂直像素?cái)?shù)
     * @param consumed 輸出參數(shù)卓鹿。消費(fèi)[0]應(yīng)設(shè)置為消耗的dx的距離留荔,消費(fèi)[1]應(yīng)設(shè)置為所消費(fèi)的dy的距離存谎。
     */
    @Override
    public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed, int type) {
        Log.i(TAG,"onNestedPreScroll dx " + dx
                + "  dy " + dy);
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed,type);
    }



    /**
     * 當(dāng)正在進(jìn)行的嵌套滾動更新并且目標(biāo)已滾動或試圖滾動時調(diào)用肥隆。
     *
     * @param coordinatorLayout 頂層嵌套布局
     * @param child 綁定behavior的View
     * @param target 被觀察的view(被觀察者,就是同級別的其他子視圖)
     * @param dxConsumed target 已經(jīng)消費(fèi)的x方向的距離
     * @param dyConsumed target 已經(jīng)消費(fèi)的y方向的距離
     * @param dxUnconsumed x 方向剩下的滾動距離
     * @param dyUnconsumed y 方向剩下的滾動距離
     */
    @Override
    public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed,
                               int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) {
        Log.i(TAG,"onNestedScroll child " + child.getClass().getSimpleName()
                + "  dependency " + target.getClass().getSimpleName());
        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed,type);
    }

    /**
     *  嵌套滾動結(jié)束時被調(diào)用恰聘,這是一個清除滾動狀態(tài)等的好時機(jī)晴叨。
     *
     * @param coordinatorLayout 頂層嵌套布局
     * @param child 綁定behavior的View(觀察者,就是TextView本身)
     * @param target 被觀察的view(被觀察者矾屯,就是同級別的其他子視圖)
     */
    @Override
    public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int type) {
        Log.i(TAG,"onStopNestedScroll child " + child.getClass().getSimpleName()
                + "  dependency " + target.getClass().getSimpleName());
        super.onStopNestedScroll(coordinatorLayout, child, target,type);
    }

    /**
     * onStartNestedScroll返回true才會觸發(fā)這個方法,接受滾動處理后回調(diào)孙技,可以在這個
     * 方法里做一些準(zhǔn)備工作,如一些狀態(tài)的重置等牵啦。
     *
     * @param coordinatorLayout 頂層嵌套布局
     * @param child 綁定behavior的View(觀察者,就是TextView本身)
     * @param directTargetChild 該子視圖是或包含嵌套滾動操作的目標(biāo)
     * @param target 被觀察的view(被觀察者,就是同級別的其他子視圖)
     * @param nestedScrollAxes 方向
     * @param type 導(dǎo)致此滾動事件的輸入類型
     */
    @Override
    public void onNestedScrollAccepted(CoordinatorLayout coordinatorLayout, View child, View directTargetChild,
                                       View target, int nestedScrollAxes,int type) {
        Log.i(TAG,"onNestedScrollAccepted child " + child.getClass().getSimpleName()
                + "  dependency " + target.getClass().getSimpleName());
        super.onNestedScrollAccepted(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes,type);
    }

    /**
     * 用戶松開手指并且會發(fā)生慣性動作之前調(diào)用楞件,參數(shù)提供了速度信息土浸,可以根據(jù)這些速度信息
     * 決定最終狀態(tài)盹愚,比如滾動Header,是讓Header處于展開狀態(tài)還是折疊狀態(tài)皆怕。返回true 表
     * 示消費(fèi)了fling.
     *
     * @param coordinatorLayout 頂層嵌套布局
     * @param child 綁定behavior的View(觀察者,就是TextView本身)
     * @param target 被觀察的view(被觀察者愈腾,就是同級別的其他子視圖)
     * @param velocityX x 方向的速度
     * @param velocityY y 方向的速度
     * @return true 行為消耗了,否則沒有
     */
    @Override
    public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, View child, View target,
                                    float velocityX, float velocityY) {
        Log.i(TAG,"onNestedPreFling child " + child.getClass().getSimpleName()
                + "  dependency " + target.getClass().getSimpleName());
        return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY);
    }



    //可以重寫這個方法對子View 進(jìn)行重新布局
    @Override
    public boolean onLayoutChild(CoordinatorLayout parent, View child, int layoutDirection) {
        Log.i(TAG,"onLayoutChild child " + child.getClass().getSimpleName());
        return super.onLayoutChild(parent, child, layoutDirection);
    }

上面的代碼用也用 TextView作為觀察者悦即,自定義它的Behavior的行為橱乱,跟隨 NestedScrollView 滑動
https://github.com/liuguangsen/HightUi/blob/master/app/src/main/java/com/liugs/materialdesigntest/behavior/BehaviorTest.java

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市泳叠,隨后出現(xiàn)的幾起案子作瞄,更是在濱河造成了極大的恐慌,老刑警劉巖危纫,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宗挥,死亡現(xiàn)場離奇詭異,居然都是意外死亡种蝶,警方通過查閱死者的電腦和手機(jī)契耿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來螃征,“玉大人搪桂,你說我怎么就攤上這事√咝担” “怎么了拙泽?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長裸燎。 經(jīng)常有香客問我顾瞻,道長,這世上最難降的妖魔是什么德绿? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任荷荤,我火速辦了婚禮,結(jié)果婚禮上移稳,老公的妹妹穿的比我還像新娘蕴纳。我一直安慰自己,他們只是感情好个粱,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布古毛。 她就那樣靜靜地躺著,像睡著了一般都许。 火紅的嫁衣襯著肌膚如雪稻薇。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天胶征,我揣著相機(jī)與錄音塞椎,去河邊找鬼。 笑死睛低,一個胖子當(dāng)著我的面吹牛案狠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播钱雷,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼骂铁,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了罩抗?” 一聲冷哼從身側(cè)響起拉庵,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎澄暮,沒想到半個月后名段,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體阱扬,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡泣懊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了麻惶。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片馍刮。...
    茶點(diǎn)故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖窃蹋,靈堂內(nèi)的尸體忽然破棺而出卡啰,到底是詐尸還是另有隱情静稻,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布匈辱,位于F島的核電站振湾,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏亡脸。R本人自食惡果不足惜押搪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望浅碾。 院中可真熱鬧大州,春花似錦、人聲如沸垂谢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽滥朱。三九已至根暑,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間徙邻,已是汗流浹背购裙。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鹃栽,地道東北人躏率。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像民鼓,于是被迫代替她去往敵國和親薇芝。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容