Behavior使用

一卤档、CoordinatorLayout

CoordinatorLayout的主要功能是協(xié)調(diào)內(nèi)部各個子控件直接的狀態(tài)關(guān)系浇垦,也就是說氯材,可以協(xié)調(diào)多個View進行互動甸私,比如:移動诚些,動畫等。它是通過Behavior皇型。代碼連接已經(jīng)放在了最下面诬烹,有需要可以下載

二、Behavior

是作用于CoordinatorLayout的子View的交互行為插件弃鸦。Google給我們提供了一些Behavior绞吁,我們也可以自己定義Behavior,代碼在最下面

1. BottomSheetBehavior

它是一個從底部彈出一個布局唬格,例如我們經(jīng)常用的分享功能

1.1 用法

image

注:我們設(shè)置了一個Behavior家破,bottom_sheet_behavior颜说,是系統(tǒng)提供好的一個behavior,如果一開始需要隱藏的話汰聋,可以設(shè)置app:behavior_peekHeight="0dp"

然后在代碼中這樣寫

image

BottomSheetBehavior有5種狀態(tài)

(1)STATE_EXPANDED展開狀態(tài)门粪,顯示完整布局。

(2)STATE_COLLAPSED折疊狀態(tài)烹困,顯示peekHeigth 的高度玄妈,如果peekHeight為0,則全部隱藏,與STATE_HIDDEN效果一樣韭邓。

(3)STATE_DRAGGING拖拽時的狀態(tài)

(4)STATE_HIDDEN隱藏時的狀態(tài)

(5)STATE_SETTLING釋放時的狀態(tài)

2. BottomSheetDialog

它是一個Dialog措近,從底部彈出一個Dialog,比如淘寶商品詳情頁的立即購買女淑,它是對BottomSheetBehavior的一個封裝瞭郑,是獲取一個Behavior,設(shè)置一個監(jiān)聽狀態(tài)的回調(diào)鸭你,設(shè)置了下滑可以隱藏

示例如下:

image

注意:系統(tǒng)的BottomSheetDialog是基于BottomSheetBehavior封裝的屈张,這里判斷了當(dāng)滑動隱藏了BottomSheetBehavior中的View后,內(nèi)部設(shè)置了BottomSheetBehavior的狀態(tài)為STATE_HIDDEN,所以我們再次調(diào)用dialog.show()的時候Dialog沒法再打開狀態(tài)為STATE_HIDE的Dialog,所以我們需要自己來實現(xiàn)袱巨,監(jiān)聽用戶滑動關(guān)閉后阁谆,把BottomSheetBehavior的狀態(tài)再設(shè)置為STATE_COLLAPSED

image

3.SwipeDissmissBehavior

滑動關(guān)閉或者滑動消失,Snackbar就是使用的這個愉老,當(dāng)滑動Snackbar的時候场绿,Snackbar消失

代碼也特別簡單,在代碼中直接new一個SwipeDissmissBehavior嫉入,設(shè)置屬性焰盗,添加到CoordinatorLayout.LayoutParams,直接代碼截圖

image

4. 自定義Behavior

Google為我們提供了一些場景使用的Behavior咒林,但是有時候熬拒,要實現(xiàn)多個View之間的交互,我們可以使用自定義Behavior

4.1 第一種是通過監(jiān)聽一個View的狀態(tài)垫竞,如果位置澎粟,大小的變化,來改變其它View的行為欢瞪,這種只需要重寫兩個方法就可以了活烙,分別是layoutDependsOn和onDependentViewChanged,layoutDependsOn方法判斷是指定依賴的View時遣鼓,返回true瓣颅,然后在onDependentViewChange里,被依賴的View做需要的行為動作

4.2 第二種就是重寫onStartNestedScroll譬正、onNestedPreScroll等

具體方法:


/**** 

* 表示是否給應(yīng)用了Behavior 的View 指定一個依賴的布局宫补,通常,當(dāng)依賴的View 布局發(fā)生變化時

* 不管被被依賴View 的順序怎樣曾我,被依賴的View也會重新布局

* @param parent

* @param child 綁定behavior 的View

* @param dependency 依賴的view

* @return 如果child 是依賴的指定的View 返回true,否則返回false

*/

@Override

public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton child, View dependency) {

return super.layoutDependsOn(parent, child, dependency);

}

/**

* 當(dāng)被依賴的View 狀態(tài)(如:位置粉怕、大小)發(fā)生變化時抒巢,這個方法被調(diào)用

* @param parent

* @param child

* @param dependency

* @return

*/

@Override

public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton child, View dependency) {

return super.onDependentViewChanged(parent, child, dependency);

}

/**

* 當(dāng)coordinatorLayout 的子View試圖開始嵌套滑動的時候被調(diào)用贫贝。當(dāng)返回值為true的時候表明

* coordinatorLayout 充當(dāng)nested scroll parent 處理這次滑動,需要注意的是只有當(dāng)返回值為true

的時候蛉谜,Behavior 才能收到后面的一些nested scroll 事件回調(diào)(如:onNestedPreScroll稚晚、onNestedScroll等)

這個方法有個重要的參數(shù)axes,表明處理的滑動的方向型诚。

* @param coordinatorLayout  和Behavior 綁定的View的父CoordinatorLayout

* @param child 和Behavior 綁定的View

* @param directTargetChild

* @param target

* @param axes 嵌套滑動 應(yīng)用的滑動方向(ViewCompat.SCROLL_AXIS_HORIZONTAL,@ViewCompat.SCROLL_AXIS_VERTICAL)

* @param type

* @return

*/

@Override

public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout,@NonNull FloatingActionButton child,@NonNull View directTargetChild,@NonNull View target,int axes,int type) {

return super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, axes);

}

/**

* 嵌套滾動發(fā)生之前被調(diào)用

* 在nested scroll child 消費掉自己的滾動距離之前客燕,嵌套滾動每次被nested scroll child

* 更新都會調(diào)用onNestedPreScroll。注意有個重要的參數(shù)consumed狰贯,可以修改這個數(shù)組表示你消費

了多少距離也搓。假設(shè)用戶滑動了100px,child 做了90px 的位移,你需要把 consumed[1]的值改成90涵紊,

這樣coordinatorLayout就能知道只處理剩下的10px的滾動傍妒。

* @param coordinatorLayout

* @param child

* @param target

* @param dx 用戶水平方向的滾動距離

* @param dy 用戶豎直方向的滾動距離

* @param consumed

* @param type

*/

@Override

public void onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout,@NonNull FloatingActionButton child,@NonNull View target,int dx,int dy,@NonNull int[] consumed,int type) {

super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);

}

/**

* 進行嵌套滾動時被調(diào)用

* @param coordinatorLayout

* @param child

* @param target

* @param dxConsumed 已經(jīng)消費的x方向的距離

* @param dyConsumed 已經(jīng)消費的y方向的距離

* @param dxUnconsumed x 方向剩下的滾動距離

* @param dyUnconsumed y 方向剩下的滾動距離

* @param type

*/

@Override

public void onNestedScroll(@NonNull CoordinatorLayout coordinatorLayout,@NonNull FloatingActionButton child,@NonNull View target,int dxConsumed,int dyConsumed,int dxUnconsumed,int dyUnconsumed,int type) {

super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type);

}

/**

* 嵌套滾動結(jié)束時被調(diào)用,這是一個清除滾動狀態(tài)等的好時機摸柄。

* @param coordinatorLayout

* @param child

* @param target

* @param type

*/

@Override

public void onStopNestedScroll(@NonNull CoordinatorLayout coordinatorLayout,@NonNull FloatingActionButton child,@NonNull View target,int type) {

super.onStopNestedScroll(coordinatorLayout, child, target, type);

}

/**

* onStartNestedScroll返回true才會觸發(fā)這個方法颤练,接受滾動處理后回調(diào),可以在這個

方法里做一些準(zhǔn)備工作驱负,如一些狀態(tài)的重置等嗦玖。

* @param coordinatorLayout

* @param child

* @param directTargetChild

* @param target

* @param axes

* @param type

*/

@Override

public void onNestedScrollAccepted(@NonNull CoordinatorLayout coordinatorLayout,@NonNull FloatingActionButton child,@NonNull View directTargetChild,@NonNull View target,int axes,int type) {

super.onNestedScrollAccepted(coordinatorLayout, child, directTargetChild, target, axes, type);

}

/**

* 用戶松開手指并且會發(fā)生慣性動作之前調(diào)用,參數(shù)提供了速度信息电媳,可以根據(jù)這些速度信息決定最終狀態(tài)踏揣,

比如滾動Header,是讓Header處于展開狀態(tài)還是折疊狀態(tài)匾乓。返回true 表示消費了fling.

* @param coordinatorLayout

* @param child

* @param target

* @param velocityX x 方向的速度

* @param velocityY y 方向的速度

* @return

*/

@Override

public boolean onNestedPreFling(@NonNull CoordinatorLayout coordinatorLayout,@NonNull FloatingActionButton child,@NonNull View target,float velocityX,float velocityY) {

return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY);

}

/**

* /可以重寫這個方法對子View 進行重新布局

* @param parent

* @param child

* @param layoutDirection

* @return

*/

@Override

public boolean onLayoutChild(CoordinatorLayout parent, FloatingActionButton child,int layoutDirection) {

return super.onLayoutChild(parent, child, layoutDirection);

}

案例:仿知乎首頁滑動隱藏/顯示

它是CoordinatorLayout的子View之間的交互捞稿,實現(xiàn)子View隨著RecyclerView的滾動顯示或者隱藏,只需要滑動一段距離拼缝,來顯示隱藏娱局,實現(xiàn)onNestedScroll(),在里面判斷View需要移動的位置咧七,然后在進行動畫移動


//向上的時候是出來衰齐,向下是隱藏

if(dyConsumed>0){//往上滑動,是隱藏,需要加一個標(biāo)志位

    if(!isOut){//不是往下走继阻,需要往下走

        CoordinatorLayout.LayoutParams params=(CoordinatorLayout.LayoutParams)child.getLayoutParams();

child.animate().translationY(params.bottomMargin+child.getMeasuredHeight()).setDuration(300).start();

//處理底部位移動畫

        mBottomTabView.animate().translationY(mBottomTabView.getMeasuredHeight()).setDuration(300).start();

isOut=true;

}

}else {//往下滑動

    if(isOut){

child.animate().translationY(0).setDuration(300).start();

//處理底部位移動畫

        mBottomTabView.animate().translationY(0).setDuration(300);

isOut=false;

}

}

注:1.自定義Behavior構(gòu)造方法一定要重載3芴巍7峡帷!不然會報錯

   2.底部移動和隱藏需要先在onLayoutChild()里面獲取底部控件id抹缕,然后再在onNestedScroll()寫移動動畫

Override

public boolean onLayoutChild(CoordinatorLayout parent, FloatingActionButton child,int layoutDirection) {

mBottomTabView = parent.findViewById(R.id.bottom_tab_layout);

return super.onLayoutChild(parent, child, layoutDirection);

}

具體代碼連接:https://github.com/sisirukou/Behavior.git

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末澈蟆,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子卓研,更是在濱河造成了極大的恐慌趴俘,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奏赘,死亡現(xiàn)場離奇詭異寥闪,居然都是意外死亡,警方通過查閱死者的電腦和手機磨淌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進店門疲憋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人伦糯,你說我怎么就攤上這事柜某。” “怎么了敛纲?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵喂击,是天一觀的道長。 經(jīng)常有香客問我淤翔,道長翰绊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任旁壮,我火速辦了婚禮监嗜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘抡谐。我一直安慰自己裁奇,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布麦撵。 她就那樣靜靜地躺著刽肠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪免胃。 梳的紋絲不亂的頭發(fā)上音五,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天,我揣著相機與錄音羔沙,去河邊找鬼躺涝。 笑死,一個胖子當(dāng)著我的面吹牛扼雏,可吹牛的內(nèi)容都是我干的坚嗜。 我是一名探鬼主播夯膀,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼惶傻!你這毒婦竟也來了棍郎?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤银室,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后励翼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蜈敢,經(jīng)...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年汽抚,在試婚紗的時候發(fā)現(xiàn)自己被綠了抓狭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,015評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡造烁,死狀恐怖否过,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情惭蟋,我是刑警寧澤苗桂,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站告组,受9級特大地震影響煤伟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜木缝,卻給世界環(huán)境...
    茶點故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一便锨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧我碟,春花似錦放案、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至恳守,卻和暖如春考婴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背催烘。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工沥阱, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人伊群。 一個月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓考杉,卻偏偏與公主長得像策精,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子崇棠,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,969評論 2 355

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