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