編輯:關於Android編程
前面我們簡單的介紹過CoordinatorLayout這個控件,這一篇我們詳細地介紹這個ASD庫中最重要的控件。
我們在NestedScrollView這個控件中有設置了一個屬性:app:layout_behavior=”@string/appbar_scrolling_view_behavior”,我們看一下完整的代碼:
在這裡,appbar_scrolling_view_behavior並不是一個字符串,而是一個類,而且這個類我們可以自定義。
這裡,我們需要引入一個新的東西這個就叫Behavior。
在這裡我們先看一下CoordinatorLayout中Behavior的官方介紹:
A Behavior implements one or more interactions that a user can take on a child view. These interactions may include drags, swipes, flings, or any other gestures.
簡單地說:一個Behavior可以提供給一個或者多個用戶在同一個子View中實現拖動、滑動、飛速滑動或者其它手勢操作。
這個Behavior是CoordinatorLayout的內部類,直接子類有:AppBarLayout.Behavior, AppBarLayout.ScrollingViewBehavior, FloatingActionButton.Behavior, SwipeDismissBehavior我們自定義的時候需要繼承於Behavior。
Behavior只有是CoordinatorLayout的直接子View才有意義,我們可以為任何View添加一個Behavior。
Behavior是一系列回調。讓開發者有機會以非侵入的方式為View添加動態的依賴布局,和處理父布局(CoordinatorLayout)滑動手勢的機會。
下面我們學習一下怎麼實現一個自定義Behavior
使用
跟ASD庫的其它控件一樣,使用SnackBar和CoordinatorLayout需要在bundle.gradle中添加如下代碼:
compile 'com.android.support:design:24.0.0'
在自定義Behavior中,如果是某個View監聽另外一個View的大小,位置,顯示狀態等狀態變化的時候,我們需要關心的是下面的三個方法:
layoutDependsOn(CoordinatorLayout parent, View child, View dependency)
onDependentViewChanged(CoordinatorLayout parent, View child, View dependency)
onDependentViewRemoved(CoordinatorLayout parent, View child, View dependency)
具體的代碼解析如下:
/**
* 必須要實現這個構造函數,因為CoordinatorLayout源碼中的parseBehavior()方法直接反射調用這個構造函數。
*
* @param context 上下文對象
* @param attrs 接收XMl中定義的屬性信息
*/
public DependentBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* 設置我們需要關心的View
*
* @param parent 當前的CoordinatorLayout
* @param child 我們設置當前Behavior的View
* @param dependency 我們需要關心的View
* @return
*/
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
return dependency instanceof Toolbar;
}
/**
* 當我們關心的View發生變化的時候,我們需要怎麼處理
*
* @param parent 當前的CoordinatorLayout
* @param child 我們設置當前Behavior的View
* @param dependency 我們需要關心的View
* @return
*/
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
}
/**
* 在layoutDependsOn返回true的基礎上之後,報告dependency被移除了
*
* @param parent 當前的CoordinatorLayout
* @param child 設置了Behavior的View
* @param dependency 設置Behavior依賴的View
*/
@Override
public void onDependentViewRemoved(CoordinatorLayout parent, View child, View dependency) {
super.onDependentViewRemoved(parent, child, dependency);
}
}
如果是監聽CoordinatorLayout裡面滑動狀態的,我們需要關心的是另外一些方法:
onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes)
onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed)
onNestedScrollAccepted(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes)
onStopNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target)
onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed)
onNestedFling(CoordinatorLayout coordinatorLayout, View child, View target, float velocityX, float velocityY, boolean consumed)
onNestedPreFling(CoordinatorLayout coordinatorLayout, View child, View target, float velocityX, float velocityY)
具體的方法解析代碼就是:
public class CustomBehavior extends CoordinatorLayout.Behavior {
public CustomBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* 有嵌套滑動到來了,問下該Behavior是否接受嵌套滑動
*
* @param coordinatorLayout 當前的CoordinatorLayout
* @param child 該Behavior對應的View
* @param directTargetChild 嵌套滑動對應的父類的子類
* @param target 具體嵌套滑動的那個子類
* @param nestedScrollAxes 支持嵌套滾動軸。水平方向,垂直方向,或者不指定
* @return 是否接受該嵌套滑動
*/
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
return super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
}
/**
* 在嵌套滑動的子View未滑動之前告訴過來的准備滑動的情況
*
* @param coordinatorLayout
* @param child 該Behavior對應的View
* @param target 具體嵌套滑動的那個子類
* @param dx 水平方向嵌套滑動的子View想要變化的距離
* @param dy 垂直方向嵌套滑動的子View想要變化的距離
* @param consumed 這個參數要我們在實現這個函數的時候指定,回頭告訴子View當前父View消耗的距離 consumed[0] 水平消耗的距離,consumed[1] 垂直消耗的距離 好讓子view做出相應的調整
*/
@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
}
/**
* Behavior接受了嵌套滑動的請求該函數調用。onStartNestedScroll返回true該函數會被調用。 參數和onStartNestedScroll一樣
*
* @param coordinatorLayout 當前的CoordinatorLayout
* @param child 該Behavior對應的View
* @param directTargetChild 嵌套滑動對應的父類的子類
* @param target 具體嵌套滑動的那個子類
* @param nestedScrollAxes 支持嵌套滾動軸。水平方向,垂直方向,或者不指定
*/
@Override
public void onNestedScrollAccepted(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
super.onNestedScrollAccepted(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
}
/**
* 停止嵌套滑動
*
* @param coordinatorLayout
* @param child 設置Behavior的View
* @param target 具體嵌套滑動的那個子類
*/
@Override
public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target) {
super.onStopNestedScroll(coordinatorLayout, child, target);
}
/**
* 嵌套滑動的子View在滑動之後報告過來的滑動情況
*
* @param coordinatorLayout
* @param child 設置Behavior的View
* @param target 具體嵌套滑動的那個子類
* @param dxConsumed 水平方向嵌套滑動的子View滑動的距離
* @param dyConsumed 垂直方向嵌套滑動的子View滑動的距離
* @param dxUnconsumed 水平方向嵌套滑動的子View未滑動的距離
* @param dyUnconsumed 垂直方向嵌套滑動的子View未滑動的距離
*/
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
}
/**
* 嵌套滑動的子View在fling之後報告過來的fling情況
*
* @param coordinatorLayout
* @param child 設置Behavior的View
* @param target 具體嵌套滑動的那個子類
* @param velocityX 水平方向速度
* @param velocityY 垂直方向速度
* @param consumed 子view是否fling了
* @return true Behavior是否消耗了fling;false Behavior沒有消耗fling
*/
@Override
public boolean onNestedFling(CoordinatorLayout coordinatorLayout, View child, View target, float velocityX, float velocityY, boolean consumed) {
return super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed);
}
/**
* 在嵌套滑動的子View未fling之前告訴過來的准備fling的情況
*
* @param coordinatorLayout
* @param child 設置Behavior的View
* @param target 具體嵌套滑動的那個子類
* @param velocityX 水平方向速度
* @param velocityY 垂直方向速度
* @return true Behavior是否消耗了fling;false Behavior沒有消耗fling
*/
@Override
public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, View child, View target, float velocityX, float velocityY) {
return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY);
}
}
最後推薦兩個強大的自定義Behavior開源項目,都在Github上,實現的效果也非常酷炫,不過邏輯比較復雜:
CoordinatorLayoutSample
CoordinatorBehaviorExample
附上效果圖:
先占個位置,下次翻譯~ :p There are a few scenarios in which your activity is destroyed due t
對於很多新手來說,自己搭建一個開發環境的確不是一件容易的事;對於“老手”的開發者,搭建開發環境同樣也是一件麻煩的事,畢竟耗時費勁。但是,如果把相關
歇了兩三天,,嘿嘿是不是感覺我沒有恆心啊。。。麼事今天咱們繼續。 今天我們學習一下CCMoveTo CCMoveBy CCscaleTo CCBlink 這四個類,比較
BaseActivity是項目中所有activity的基類,含有一些公共的屬性和方法,同時控制toolbar的顯示,以及其他一些功能。。。來看源碼:/** * BaseA