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

相关文章
相关标签/搜索