CoordinatorLayout
CoordinatorLayout(协调者布局)是在 Google IO/15 大会发布的,遵循Material 风格,包含在 supportLibrary中,结合AppbarLayout, CollapsingToolbarLayout等 可 产生各种炫酷的效果CoordinatorLayout是用来协调其子view并以触摸影响布局的形式产生动画效果的一个super-poweredFrameLayout,CoordinatorLayout是一个顶级父View。它本身没什么属性设置。若要使用到协调者布局模式,则最外层需要包裹它。
CoordinatorLayout主要通过Behavior来实现协调者,一般我们会给相应的子View添加一个类似app:layout_behavior="@string/appbar_scrolling_view_behavior"。当然我们这里也可以自定义。
AppBarLayout
AppBarLayout是LinearLayout的子类,必须在它的子view上设置app:layout_scrollFlags属性或者是在代码中调用setScrollFlags()设置这个属性。
AppBarLayout的子布局有5种滚动标识:
scroll:所有想滚动出屏幕的view都需要设置这个flag, 没有设置这个flag的view将被固定在屏幕顶部。
enterAlways:这个flag让任意向下的滚动都会导致该view变为可见,启用快速“返回模式”。
enterAlwaysCollapsed:假设你定义了一个最小高度(minHeight)同时enterAlways也定义了,那么view将在到达这个最小高度的时候开始显示,并且从这个时候开始慢慢展开,当滚动到顶部的时候展开完。
exitUntilCollapsed:当你定义了一个minHeight,此布局将在滚动到达这个最小高度的时候折叠。
snap:当一个滚动事件结束,如果视图是部分可见的,那么它将被滚动到收缩或展开。例如,如果视图只有底部25%显示,它将折叠。相反,如果它的底部75%可见,那么它将完全展开。
依次对应:enterAlways、enterAlwaysCollapsed、exitUntilCollapsed、scroll、snap
CollapsingToolbarLayout
是提供了一个可以折叠的Toolbar,它继承自FrameLayout,给它设置layout_scrollFlags,它可以控制包含在CollapsingToolbarLayout中的控件(如:ImageView、Toolbar)在响应layout_behavior事件时作出相应的scrollFlags滚动事件(移除屏幕或固定在屏幕顶端)。CollapsingToolbarLayout可以通过app:contentScrim设置折叠时工具栏布局的颜色,通过
app:statusBarScrim设置折叠时状态栏的颜色。默认contentScrim是colorPrimary的色值,statusBarScrim是colorPrimaryDark的色值。CollapsingToolbarLayout的子布局有3种折叠模式(Toolbar中设置的app:layout_collapseMode)
基本行为属性
off:默认属性,布局将正常显示,无折叠行为。
pin:CollapsingToolbarLayout折叠后,此布局将固定在顶部。
parallax:CollapsingToolbarLayout折叠时,此布局也会有视差折叠效果。
常用属性
Title,当布局内容全部显示出来时,title是最大的,但是随着View逐步移出屏幕顶部,title变得越来越小。在代码中可以通过调用setTitle函数来设置title。注意,Toolbar的title必须通过该属性来设置,通过自己的属性来设置无效
ExpandedTitleColor/CollapsedTitleTextColor,设置还没收缩时状态下字体颜色与收缩后Toolbar上字体的颜色。当设置这两个属性后,在动画过程中Android系统会自动配置好过渡效果。
expandedTitleTextAppearance/collapsedTitleTextAppearance,设置未折叠状态下字体样式和设置折叠后字体样式。
expendsTitleMargin,可以给未折叠时字体四周的margin值
contentScrim,这是ToolBar被折叠到顶部固定后的背景。
Status bar scrim,根据滚动位置是否到达一个阀值决定是否对状态栏“盖上纱布”,你可以通过setStatusBarScrim(Drawable)来设置纱布图片,但是只能在LOLLIPOP设备上面有作用。
layout_collapseParallaxMultiplier,CollapsingToolbarLayout滑动时,子视图的视觉差。这个值的范围为0.0-1.0之间。为0的时候,你可以感觉到视图完全随NestedScrollView滚动;为1的时候,似乎又是完全不滚动。
折叠模式(layout_collpaseMode)
pin模式:即固定模式,在折叠的时候最后固定在顶端
parallax模式:即视差模式,在折叠的时候会有个视差折叠的效果
Behavior
CoordinatorLayout中子View的交互行为,可以在CoordinatorLayout的子类中实现一个或多个交互,这些交互可能是拖动,滑动,闪动或任何其他手势。其实就是实现CoordinatorLayout内部控件的交互行为,可以在非侵入的方式实现相应的交互
Behavior只有是CoordinatorLayout的直接子View才有意义。只要将Behavior绑定到CoordinatorLayout的直接子元素上,就能对触摸事件(touch events)、window insets、measurement、layout以及嵌套滚动(nested scrolling)等动作进行拦截。Design Library的大多功能都是借助Behavior的大量运用来实现的。当然,Behavior无法独立完成工作,必须与实际调用的CoordinatorLayout子视图相绑定。具体有三种方式:通过代码绑定、在XML中绑定或者通过注释实现
自动绑定。上面NestedScrollView中app:layout_behavior=”@string/appbar_scrolling_view_behavior”的Behavior是系统默认的,我们也可以根据自己的需求来自定义Behavior。
Behavior里面回调的说明
layoutDependsOn(CoordinatorLayout parent, View child, View dependency) 表示是否给应用了Behavior 的View 指定一个依赖的布局
参数1:coordinatorlayout对象
参数2:child 被观察的View
参数3:依赖变化的View(被观察的View)
onDependentViewChanged(CoordinatorLayout parent, View child, View dependency)
当依赖的View发生变化的时候掉的方法
onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNullView child, @NonNull View directTargetChild, @NonNull View target, int axes, inttype)
当用户手指按下的时候,你是否要处理这次操作。当你确定要处理这次操作的时候,返回true;如果返回false的时候,就不会去响应后面的回调事件了。你想怎么滑就怎么话,我都不做处理。这里的(axes)滚动方向很重要,可以通过此参数判断滚动方向!
参数3:直接目标,相当于能滑动的控件
参数4:观察的View
参数5:这个可以简单理解为滚动方向
ViewCompat#SCROLL_AXIS_HORIZONTAL 水平方向
ViewCompat#SCROLL_AXIS_VERTICAL 竖直方向
参数6:这个参数是之后有的,如果你输入的类型不是TYPE_TOUCH那么就不会相应这个滚动
onNestedScrollAccepted(@NonNull CoordinatorLayout coordinatorLayout, @NonNull
V child, @NonNull View directTargetChild, @NonNull View target, @ScrollAxis int axes,
@NestedScrollType int type) 当onStartNestedScroll准备处理这次滑动的时候(返回true的时
候),回调这个方法。可以在这个方法中做一些响应的准备工作!
onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View
child, @NonNull View target, int dx, int dy, @NonNull int[] consumed,
@NestedScrollType int type)
当滚动开始执行的时候回调这个方法。参数4/参数5:用户x/y轴滚动的距离(注意这里是每一次都回调的啊!!!)
参数6:处理滚动的距离的参数,内部维护着输出距离,假设用户滑动了100px,child 做了90px的位移,你需要把consumed[1]的值改成90,这样coordinatorLayout就能知道只处理剩下的10px的滚动。其中consumed[0]代表x轴、consumed[1]代表y轴。可能你不理解这个问题,换个形象点的比喻,比如你开发某一个功能,但是你只会其中的90%那么怎么办呢?不能就不管了。好你找到了你的同事或者老大,让他去完成剩下的10%。这样问题就完美的解决了,是一个概念的!
onNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull Viewchild, @NonNull View target, int dxConsumed, int dyConsumed, int dxUnconsumed,int dyUnconsumed, int type)
上面这个方法结束的时候,coordinatorLayout处理剩下的距离,比如还剩10px。但是coordinatorLayout发现滚动2px的时候就已经到头了。那么结束其滚动,调用该方法,并将coordinatorLayout处理剩下的像素数作为参 (dxUnconsumed、dyUnconsumed) 传过来,这里传过来的就是 8px。参数中还会有coordinatorLayout处理过的像素数(dxConsumed、dyConsumed)。老大开始处理剩下的距离了!这个方法主要处理一些越界后的滚动。还是不懂对吧!还拿你们老大做比喻:比如上面还剩 10%的工作,这时老大处理了2%后发现已经可以上线了,于是老大结束了工作,并将处理剩下的内容(dxUnconsumed、dyUnconsumed)纪录下来,告诉你。老大处理了的内容(dxConsumed、dyConsumed)也告诉了你。
参数4/参数5:当没有滚动到顶部或者底部的时候,x/y轴的滚动距离
参数6/参数7:当滚动到顶部或者底部的时候,x/y轴的滚动距离
onNestedPreFling(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child,@NonNull View target, float velocityX, float velocityY) 当手指松开发生惯性动作之前调用,这里提供了响应的速度,你可以根据速度判断是否需要进行折叠等一系列的操作,你要确定响应这个方法的话,返回true。
参数4/参数5:代表相应的速度
onStopNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child,@NonNull View target, int type) 停止滚动的时候回调的方法。当你不去响应Fling的时候会直接回调这个方法。在这里可以做一些清理工作。或者其他的内容。。。
onLayoutChild(CoordinatorLayout parent, View child, int layoutDirection) 确定子View位置的方法,这个方法可以重新定义子View的位置(这里明确是设置behavior的那个View哦),例如下面这样
ViewCompat#LAYOUT_DIRECTION_LTR 视图方向从左到右
ViewCompat#LAYOUT_DIRECTION_RTL 视图方向从优到左
基本实现
然后就可以在
一般自定义behavior,我们需要实现CoordinatorLayout.Behavior接口,主要重写 boolean layoutDependsOn()和boolean onDependentViewChanged方法实现需求。