Android Support Design 中 CoordinatorLayout 與 Behaviors 初探
在Android M Preview發(fā)布后,我們獲得了一個新的support library —— Android Design Support Library 用來實現(xiàn)Google的Material Design 提供了一系列符合設(shè)計標(biāo)準(zhǔn)的控件。
其中有眾多的控件,其中最復(fù)雜,功能***大的就是CoordinatorLayout,顧名思義,它是用來組織它的子views之間協(xié)作的一個父view。CoordinatorLayout默認(rèn)情況下可理解是一個FrameLayout,它的布局方式默認(rèn)是一層一層疊上去。
那么,CoordinatorLayout的神奇之處就在于Behavior對象了。
看下CoordinatorLayout.Behavior對象的 Overview
- Interaction behavior plugin for child views of CoordinatorLayout.
- 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對象是用來給CoordinatorLayout的子view們進行交互用的。
Behavior接口擁有很多個方法,我們拿AppBarLayout為例。AppBarLayout中有兩個Behavior,一個是拿來給它自己用的,另一個是拿來給它的兄弟結(jié)點用的,我們重點關(guān)注下AppBarLayout.ScrollingViewBehavior這個類。
我們看下這個類中的以下方法
0. dependency
- public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
- return dependency instanceof AppBarLayout;
- }
這個方法告訴CoordinatorLayout,這個view是依賴AppBarLayout的,后續(xù)父親可以利用這個方法,查找到這個child所有依賴的兄弟結(jié)點。
1. measure
- public boolean onMeasureChild(CoordinatorLayout parent, View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed)
這個是CoordinatorLayout在進行measure的過程中,利用Behavior對象對子view進行大小測量的一個方法。
在這個方法內(nèi),我們可以通過parent.getDependencies(child);這個方法,獲取到這個child依賴的view,然后通過獲取這個child依賴的view的大小來決定自身的大小。
2. layout
- public boolean onLayoutChild(CoordinatorLayout parent, View child, int layoutDirection)
這個方法是用來子view用來布局自身使用,如果依賴其他view,那么系統(tǒng)會首先調(diào)用
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency)
這個方法,可以在這個回調(diào)中記錄dependency的一些位置信息,在onLayoutChild中利用保存下來的信息進行計算,然后得到自身的具體位置。
3. nested scroll
- public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes)
- public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed)
- public void onNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed)
- public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target)
這幾個方法是不是特別熟悉?我在Android嵌套滑動機制(NestedScrolling) 介紹過,這幾個方法剛好是NestedScrollingParent的方法,也就是對CoodinatorLayout進行的一個代理(Proxy),即CoordinatorLayout自己不對這些消息進行處理,而是傳遞給子view的Behavior,進行處理。利用這樣的方法,實現(xiàn)了view和view之間的交互和視覺的協(xié)同(布局、滑動)。
總結(jié)
可以看到CoodinatorLayout給我們實現(xiàn)了一個可以被子view代理實現(xiàn)方法的一個布局。這和傳統(tǒng)的ViewGroup不同,子view從此知道了彼此之間的存在,一個子view的變化可以通知到另一個子view。CoordinatorLayout所做的事情就是當(dāng)成一個通信的橋梁,連接不同的view。使用Behavior對象進行通信。
我們具體的實現(xiàn)可以參照 Android官方文檔告訴我們的每一個方法的作用 進行重寫,實現(xiàn)自己想要的各種復(fù)雜的功能。
https://developer.android.com/reference/android/support/design/widget/...
有了這么一套機制,想實現(xiàn)組件之間的交互,就更加方便快捷啦~