原版解释请参考google developer的文章
使用CoordinatorLayout只能使用design Library里面的控件来实现炫酷的效果,如果你使用的是以前老的控件,那么他和FrameLayout没有任何的区别。
CoordinatorLayout的不同之处在哪里呢,它的不同来源于CoordinatorLayout.Behaviors,通过这个Behavior可以截取触摸事件,屏幕插入,测量尺寸,添加布局,滚动嵌套。
创建一个Behavior:
这里使用的是泛型来新建Behavior,当然你也可以指定为某个特定的View类型。
Behavior怎么才会工作呢:
they need to be attached to a child View of a CoordinatorLayout to actually be called. 就是说需要附加在CoordinatorLayout的子View上才会被调用。
一 :在程序中:当你觉得CoordinatorLayout的每一个View都需要附加Behavior的时候使用。Behavior其实是存放在View的LayoutParams上的,只有CoordinatorLayout的直接ziView才有存放Behavior的类。这也是为什么Behavior必须声明在CoordinatorLayout的直接子类上,因为只有CoordinatorLayout的直接子View才会有Behavior-storing 类,它是LayoutParams的一个子类(Behavior-storing subclass of LayoutParams)。
在上面的例子中,使用的是默认的无参构造函数,当然可以根据需要来传递自己需要的参数。
二 :在XML中使用
FancyBehavior(Context context, AttributeSet attrs) constructor is always the one called,意思是说在xml里面的这一句调用的是这个有参的构造函数构造的对象。你还可以自定义属性(attributes)然后从xml的attributeSet中提取出来——如果你想通过xml来定制特殊功能的Behavior这是非常重要的。 注意:自定义xml属性的命名的规范类似于布局xml(layout_naming),自定义Behavior的xml属性的命名规范为behavior_prefix.
三 :自动附加到自定义控件(其实就是继承FrameLayout,再添加个Behavior)
其实看到这里,我们也明白了,其实CoordinatorLayout其实就是给FrameLayout添加一个Behavior,而直接使用系统的CoordinatorLayout其实就是使用了系统定义的Behavior。(这样使用调用的是默认的构造方法)。
拦截触摸事件
拦截触摸事件是Behavior做的事情之一,我们知道,其实所有的Layout都继承于ViewGroup。在不是CoordinatorLayout的ViewGroup中,拦截触摸事件都在ViewGroup的子类中进行(具体请看ViewGroup事件处理)。
但是在CoordinatorLayout中,CoordinatorLayout通过把ViewGroup的onInterceptTouchEvent()转移到Behavior的onInterceptTouchEvent()中,如果这个方法返回为true,Behavior将在onTouchEvent() 获取到所有的touch events。所有的CoordinatorLayout的子View都不需要知道做什么,这也是为什么SwipeDismissBehavior 能应用在所有的View上的原因。
如果你想阻断所有的交互,blocksInteractionBelow() 方法返回true即可。阻断了触摸事件之后可能还需要有个不可触摸的明显提示,这就是为什么blocksInteractionBelow() 方法依赖于getScrimOpacity() 的原因。getScrimOpacity() 返回一个不为零的数值并且覆盖一层颜色在View上,以此来提示view不可触摸,提升用户体验。