Behavior
Behavior 只有用在 CoordinatorLayout 的直接子 View 上才有效光戈,他是 CoordinatorLayout 滾動事件的一系列回調(diào)漓拾。
自定義 Behavior 繼承哪個類?
我們找到 CoordinatorLayout.Behavior 類后ctrl+h(as快捷鍵)發(fā)現(xiàn)有很多實現(xiàn)類畦木,現(xiàn)在要實現(xiàn)的是 Fab 按鈕的隱藏和顯示,仔細尋找后發(fā)現(xiàn)在眾多實現(xiàn)類中有一個 FloatingActionButton.Behavior 过牙,他就是要繼承的實現(xiàn)類愕宋。
自定義 Behavior 的實現(xiàn)
首先要繼承FloatingActionButton.Behavior
public class MyBehavior extends FloatingActionButton.Behavior {
public MyBehavior(Context context, AttributeSet attrs) {
super();
}
}
這里有個重要的地方:自定義 Behavior 繼承 FloatingActionButton.Behavior 之后要重寫他有兩個參數(shù)的構(gòu)造方法埋市,這是因為 Behavior 是 CoordinatorLayout 的內(nèi)部類, CoordnatorLayout 是通過反射來從布局文件里面我們定義的 Behavior 屬性創(chuàng)建 Behavior 的煞肾,創(chuàng)建時調(diào)用的構(gòu)造方法就是那個帶兩個參數(shù)的構(gòu)造方法咧织。
然后實現(xiàn)里面重要的三個方法
// 頁面開始滑動。
boolean onStartNestedScroll(CoordinatorLayout l, FloatingActionButton c, View directTargetChild, View v, int nestedScrollAxes);
// 頁面正在滑動籍救。
void onNestedScroll(CoordinatorLayout l, FloatingActionButton child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed);
// 頁面停止滑動
onStopNestedScroll();
onStartNestedScroll
當CoordinatorLayout里的滾動控件開始滾動的時候被調(diào)用习绢,這個方法的最后一個參數(shù)表示當前頁面的滾動方向是橫向還是垂直的,現(xiàn)在要監(jiān)聽的是垂直方向的滾動蝙昙,故判斷這個值是否是ViewCompat.SCROLL_AXIS_VERTICAL闪萄,如果是則返回true,當前滾動的方向是我們需要監(jiān)聽的
boolean onStartNestedScroll(CoordinatorLayout l, FloatingActionButton c, View directTargetChild, View v, int nestedScrollAxes){
return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL;
}
onNestedScroll
頁面滾動時被調(diào)用(手指觸摸屏幕開始移動時奇颠,只要手指移動就會調(diào)用败去,當然,這取決于onStartNestedScroll的返回值烈拒,比如手指在橫向滑動圆裕,但是onStartNestedScroll返回false,那么這個方法不會被調(diào)用荆几,只有當onStartNestedScroll返回true這個方法才會被調(diào)用葫辐,而onStartNestedScroll的返回值取決于你需要監(jiān)聽的方向),我們就在這個方法中實現(xiàn)Fab的顯示/隱藏伴郁,這個方法接收七個參數(shù),前三個參數(shù)不用介紹了蛋叼,重點介紹后面四個參數(shù)
- int dxConsumed
- 當頁面在橫向方向有滑動的時候(不是手指的滑動焊傅,是頁面上的像素點在x方向發(fā)生的變化),這個值就會變化狈涮。比如當頁面向右滑動(x的正方向)狐胎,滑動多少個點這個值就是多少
- int dxUnconsumed
- 頁面滑動到頂或滑動到底手指還在滑動,這個值就會變化歌馍,當頁面滑動到底手指還在上拉握巢,這個值就會出現(xiàn)負值,值的大小取決于滑動到底后再向上拉的長度
dyConsumed和dyUnconsumed同上面兩個道理相同松却,只是用于y軸(垂直方向)暴浦。
我們現(xiàn)在要實現(xiàn)的是頁面向上滾動時Fab隱藏溅话,頁面向下滾動時Fab顯示。所以我們需要用到的是dyConsumed
和dyUnconsumed
這兩個參數(shù)
public void onNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
//頁面向上滑動像素數(shù)大于0 || 拉到底還在向上拉 && 退出動畫是否正在執(zhí)行 && FAB按鈕當前顯示中
if ((dyConsumed > 0 || dyUnconsumed > 0) && !isAnimatingOut && child.getVisibility() == View.VISIBLE) {
//隱藏Fab
child.hide();
} else if ((dyConsumed < 0 || dyUnconsumed < 0) && child.getVisibility() != View.VISIBLE) {
//顯示Fab按鈕
child.show();
}
}
在這段代碼中我們通過判斷界面的滾動和當前Fab的顯示隱藏狀態(tài)來做相應的操作歌焦,在這里Fab有自己的顯示隱藏功能飞几,如果是其他View需要自己寫動畫相關(guān)的代碼。
onStopNestedScroll
Fab的顯示和隱藏的動畫已經(jīng)在 onNestedScroll 方法中實現(xiàn)了独撇,所以這個方法在這里不再贅述屑墨。
最后
到這里,一個自定義的用于Fab按鈕的Behavior就寫完了纷铣。
只需要在xml代碼中給Fab按鈕寫如下屬性卵史,即可使用
<android.support.design.widget.FloatingActionButton
......
app:layout_behavior="包名.MyBehavior" />
當然,F(xiàn)ab按鈕的父容器得是CoordinatorLayout