Android 優化交互 —— CoordinatorLayout 與 Behavior

前言

若是你已經很時髦的用上了AppBarTabLayoutFloatActionButton,以及Snackbar的話,我想你多多少少確定知道CoordinatorLayout這個東西。 它的神祕感來自於在佈局文件 (xml) 和代碼調用上徹底看不出和其餘組件任何的耦合,卻能作出一些神奇酷炫的交互效果。git

clipboard.png

對,沒錯,今天咱們就着重講一下CoordinatorLayout 是如何工做的,或者說,是如何讓別的組件親密無間的「合做」起來的(以及,順便會打下一點點的廣告)。github

CoordinatorLayout 究竟是幹嗎的?

顧名思義,CoordinatorLayout專一於把它的子View鏈接起來,使他們之間相互很好的配合。數組

那麼既然是合做,CoordinatorLayout的職責充當了一個第三方的角色,通知各個子View之間狀態的變換,的確,它也只幹了這麼一件事,很是純潔&純粹。佈局

那麼既然有通知,必定須要媒介,總不能把子View所有改形成適合如今這種模式的模樣吧?這樣也太不OO了,這裏的介質就是BehaviorBehaviorCoordinatorLayout用來和各個子View通訊用的代理類。spa

來自Behavior的代理 —— 佈局

CoordinatorLayout經過Behavior控制子類

注意箭頭的走向,CoordinatorLayout是經過Behavior去控制子視圖,也就表明Behavior的數據傳導基本上是單向的。當CoordinatorLayout須要進行measurelayout的時候,都會經過behavior詢問子視圖,是否須要進行相應的操做,若是不須要,就進行默認的行爲,咱們來看下onLayoutChildonMeasureChild兩個再熟悉不過的行爲。代理

clipboard.png

clipboard.png

能夠看@return的說明,若是Behavior處理了相關的操做,那麼就會覆蓋CoordinatorLayout默認的行爲(其實它的默認行爲和FrameLayout簡直如出一轍)code

這一節簡單的說了CoordinatorLayout如何經過Behavior來控制子View的佈局相關的行爲,接下來咱們看看重點的交互部分。xml

來自Behavior的代理 —— 觸摸事件之普通流程

CoordinatorLayout的功能固然不只僅是經過Behavior來控制子視圖的佈局,控制觸摸的流程纔是大頭。對象

首先咱們知道,控制觸摸事件,通常有2個:接口

  1. onInterceptTouchEvent.

  2. onTouchEvent

這裏不解釋他們之間的區別,咱們看到在Behavior中也有這麼兩個方法。

clipboard.png

clipboard.png

若是你的View所擁有的Behavior 處理了相關的事件,那麼接下去發到CoordinatorLayout上的觸摸事件就會像正常流程同樣發到這個Behavior中。

咱們終於能夠實如今不子類化View的狀況下,重寫它的觸摸事件啦。

來自Behavior的代理 —— 觸摸事件之 NestedScrolling

這纔是重點中的重點啊!!
首先,咱們來睜大眼睛看!

clipboard.png

好,能夠看見CoordinatorLayout是實現了NestedScrollingParent接口的,也就是說,要用到這個特性的話,默認不實現NestedScrollingChild接口 (pre Lollipop) 且不調用dispatchNestedScroll相關接口的View靠一邊去! 【ListView 哭暈在廁所】

CoordinatorLayout正是從NestedScrollingParent相關的接口中,獲取到嵌套滾動相關的參數,再經過Behavior傳到各個子View中,包含BehaviorView這時候才成爲真正處理嵌套滾動的對象,消費掉一些滾動參數後,再把消費掉的數值傳回到發生觸摸事件的View中,達到交互的目的。

clipboard.png

consumed這個數組能夠在View0中獲取到,表示的意思是它的NestedScrollParent消費了多少的滑動量,意味着它能使用的滑動量要減去數組裏的值。
這樣產生滑動的View就經過CoordinatorLayout和 其餘的ViewBehavior 產生了交互,咱們能夠在Behavior 中給View生成一些位置的偏移量,達到視圖上移動的效果。

來自Behavior的代理 —— layoutDependency

佈局依賴,這也是個很重要的東西,好比FAB的位置須要在Snackbar上邊,須要依賴它來操做。
主要有2個接口(用的比較少的暫時忽略):

  1. layoutDependsOn

  2. onLayoutDependencyChanged

第二個接口一般在onPreDraw或者onNestedScroll系列的回調中 最後進行調用,注意:它並非在onLayout過程當中回調的

第一個很顯然是告訴CoordinatorLayout,一個View是否依賴於另外一個View。

第二個是CoordinatorLayout發現存在依賴的時候,把被依賴方回調給依賴方由於這時候,layout已經完成,咱們能夠獲取被依賴方的全部佈局信息,根據佈局信息,使用offset來決定依賴方的一些位置;同時在這個時候,你也能夠調用requestLayout進行從新佈局。

最後的最後

好了, Guang Gao Time:

SegmentFault for Android 新版在奮力開發中,帶着對Material Design的執着,強勢歸來!

圖片描述

歡迎關注我Github 以及 @Gemini

相關文章
相關標籤/搜索