CoordinatorLayout简介
CoordinatorLayout是在Google IO/15 大会发布的,遵循Material风格,包含在support Library中,结合AppbarLayout、CollapsingToolbarLayout等可产生各种炫酷的效果。
CoordinatorLayout是加强版的FrameLayout,但并不是直接继承,基本的布局方式跟FrameLayout是一样的。主要有两个用途:
- 用作应用的顶层布局管理器,也就是作为用户界面中所有UI控件的容器;
- 用作相互之间具有特定交互行为的UI控件的容器,通过为CoordinatorLayout的子View指定Behavior,就可以实现它们之间的交互行为。 Behavior可以用来实现一系列的交互行为和布局变化,比如说侧滑菜单,可滑动删除的UI元素,以及跟随着其它UI控件移动的按钮等。
与child之间的互动
CoordinatorLayout主要提供了三种方式来实现child之间的互动:anchor、insetEdge、Behaviors
anchor
关键属性:layout_anchor和layout_anchorGravity,child B通过layout_anchor设置child A为anchor,再通过layout_anchorGravity来根据需要设置属性,这样B就可以以A的位移相应的位移了。代码如下:
先设置一个被观察的child A的id:
1 | <com.wy521angel.coordinatorlayouttest.TouchView |
然后在另一个观察的child B的设置两个参数,layout_anchor和layout_anchorGravity:
1 | <View |
B就会随着A的移动而跟着移动,效果如下图:

insetEdge
child A通过layout_insetEdge来设置插入CoordinatorLayout的方向,child B通过设置layout_dodgeInsetEdges来躲避来自相同方向的A,这样就可以避免产生重叠。
先在被观察的child A中设置参数layout_insetEdge:
1 | <com.wy521angel.coordinatorlayouttest.TouchView |
在观察的child B中设置参数layout_dodgeInsetEdges:
1 | <View |
效果如CoordinatorLayout与child之间互动图中的黑块。
Behaviors
与其它控件联合使用
FloatingActionButton
FloatingActionButton单独使用,布局如下:
1 |
|
点击按钮弹出一个Snackbar:
1 |
|
效果如下:

按钮会被Snackbar遮挡,此时需要使用到CoordinatorLayout,与CoordinatorLayout一起使用,布局调整如下:
1 |
|
原因是FloatingActionButton自带app:layout_dodgeInsetEdges=”bottom”,
而Snackbar自带app:layout_insetEdge=”bottom”,所以当Snackbar出现的时候FloatingActionButton能发生躲避行为。
我们还可以自己加一个View来验证一下Snackbar是自带app:layout_insetEdge=”bottom”
1 | <View |
这个view加入了app:layout_dodgeInsetEdges=”bottom就可以产生和FloatingActionButton一样的行为,效果如下:

AppBarLayout
AppBarLayout继承自LinearLayout,基本布局方式跟LinearLayout是一样的。AppBarLayout必须作为CoordinatorLayout的直接子View,否则它的大部分功能将不会生效,如layout_scrollFlags等。
看如下效果图:

上面这个效果在不少APP中都很常见,标题栏会随着视图的滚动显示和隐藏。
不使用CoordinatorLayout,实现这个效果的方案有两种:
- 自己处理触摸事件的分发来改变标题栏的位置。
- 使用NestedScrolling机制。
NestedScrolling两个重要的概念:
- NestedScrollingParent
- NestedScrollingChild
CoordinatorLayout已经实现了NestedScrollingParent接口,所以配合一个实现了NestedScrollingChild接口的View就可以轻松的实现以上效果,类似如下控件:NavigationMenuView、NestedScrollView、RecyclerView、SwipeRefreshLayout等等。最常用的应该是NestedScrollView和RecyclerView,注意ScrollView是不可以的。
简单起见,我们使用NestedScrollView包裹TextView来实现上面的效果,主要布局代码如下:
1 |
|
CoordinatorLayout中可滚动的视图(如本例中的NestedScrollView),需要设置以下属性:
1 | app:layout_behavior="@string/appbar_scrolling_view_behavior" |
这个固定字符串是系统提供的,表示使用android.support.design.widget.AppBarLayout$ScrollingViewBehavior来处理NestedScrollView与AppBarLayout的关系。
使用AppBarLayout的关键点是,在Child里面设置属性layout_scrollFlags,layout_scrollFlags可以设置如下5个参数:
- scroll
- snap
- enterAlways
- enterAlwaysCollapsed
- exitUntilCollapsed
scroll
这参数是其它四个参数的基础,即只有设置了这个参数,其它参数才会生效。相应的Child才会对滚动view的滚动响应。
1 | app:layout_scrollFlags="scroll" |
scroll隐藏的时候,先整体向上滚动,直到AppBarLayout完全隐藏,再开始滚动Scrolling View;显示的时候,直到Scrolling View顶部完全出现后,再开始滚动AppBarLayout到完全显示,如AppBarLayout基本效果图所示。
除了scroll,其它几个参数都必须与scroll一起使用 “|” 运算符。
snap
这个参数的作用是让Child具有吸附效果,抬手后会根据距离向上或向下滑动。
1 | app:layout_scrollFlags="scroll|snap" |
enterAlways
enterAlways与scroll类似,只不过向下滚动先显示AppBarLayout到完全,再滚动 Scrolling View。
1 | app:layout_scrollFlags="scroll|enterAlways" |
效果如下:

enterAlwaysCollapsed
这个参数是enterAlways的附加值,需要和enterAlways一起使用,和enterAlways不一样的是,不会显示AppBarLayout到完全再滚动Scrolling View,而是先滚动AppBarLayout到最小高度,再滚动Scrolling View,最后再滚动AppBarLayout到完全显示。此外还需要定义View的最小高度才有效果:
1 | android:minHeight="10dp" |
效果如下:

exitUntilCollapsed
定义了AppBarLayout消失的规则。发生向上滚动事件时,AppBarLayout向上滚动退出直至最小高度(minHeight),然后Scrolling View开始滚动。也就是AppBarLayout不会完全退出屏幕。
1 | android:minHeight="10dp" |
效果如下:

enterAlwaysCollapsed与exitUntilCollapsed在实际的使用中,更多的是与CollapsingToolbarLayout一起使用,继续看下一节。
CollapsingToolbarLayout
CollapsingToolbarLayout继承自FrameLayout,所以布局特性和FrameLayout一样。简单来说,它是工具栏的包装器,是带有视差动效的toolbar,是放在AppBarLayout中的一个直接子View。主要实现以下功能:
- Collapsing title(可以折叠的标题 )
- Content scrim(内容装饰),当我们滑动的位置到达一定阀值的时候,内容装饰将会被显示或者隐藏;
- Status bar scrim(状态栏布)
- Parallax scrolling children,滑动的时候子View呈现视觉特差效果
- Pinned position children,固定位置的子View
看如下基本布局:
1 |
|
结合enterAlwaysCollapsed使用,效果如下:

修改下CollapsingToolbarLayout的layout_scrollFlags:
1 | app:layout_scrollFlags="scroll|exitUntilCollapsed" |
效果如下:

下面简单介绍一下CollapsingToolbarLayout的几个属性:
collapsedTitleTextAppearance,expandedTitleTextAppearance
这两个可以定制标题收起和展开的字体样式contentScrim
参数可以是color和drawable,简单来说就是收起状态Toolbar的背景layout_collapseMode
说明CollapsingToolbarLayout的child可以设置为两种模式,parallax和pinpin
简单的固定模式parallax
表示视差模式,即移动过程中两个View的位置产生了一定的视觉差异。可以根据需要搭配layout_collapseParallaxMultiplier,layout_collapseParallaxMultiplier的数值是0~1。0表示滚动没有视差,完全跟着下面的滚动view,1表示不动
如下两个效果图,设置为0时,背景图片是随着滚动视图滚动的,设置为1时,则不随着滚动。


此外,不要在toolbar运行时手动添加view到toolbar里面。
ViewPager
布局如下:
1 |
|
TabLayout在滑动的时候最终会停靠在最顶部,是因为没有设置其layout_scrollFlags,即TabLayout是静态的。
参考资料:
Xugter CoordinatorLayout系列(一):基本使用
zhuhf CoordinatorLayout 完全解析
gdutxiaoxu 使用CoordinatorLayout打造各种炫酷的效果