Android CoordinatorLayout 协调布局
本篇主要介绍一下四个布局控件,他们之间相互配合可以创造出流畅的动画,实现各种复杂的效果
- CoordinatorLayout
- AppBarLayout
- CollapsingToolbarLayout
- ToolBar
CoordinatorLayout
CoordinatorLayout 是功能强大的FrameLayout。
CoordinatorLayout主要有两个用途
- 用作应用的顶层布局管理器,作为界面其他控件的父容器
- 作为与一个或多个子视图进行特定交互的容器
通过为CoordinatorLayout的子View指定不同的Behavior(默认的Behavior或自定义的Behavior),就可以实现它们之间许多复杂的交互行为,例如侧滑,移动,滑动等
Android嵌套滑动机制
先看下源码的继承关系:
public class CoordinatorLayout extends ViewGroup implements NestedScrollingParent {}
要完成嵌套滑动 这样的交互,父View需要实现 NestedScrollingParent 接口,而子View需要实现 NestedScrollingChild 接口。
CoordinatorLayout其实是NestedScrollingParent的实现类,也就意味着它的子View一定会实现NestedScrollingChild接口,这样一起协同完成复杂的滑动交互。
AppBarLayout
AppBarLayout是一个垂直的LinearLayout,只有作为CoordinatorLayout的直接子View时才能正常工作,可以通过设置layout_scrollFlags属性或setScrollFlags()方法让AppBarLayout的子View具有“滚动行为”
看一个最简单应用例子
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="@color/colorPrimary"
android:minHeight="50dp"
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"></LinearLayout>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"></android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"></android.support.v7.widget.RecyclerView>
</android.support.design.widget.CoordinatorLayout>
</LinearLayout>
效果如下:
AppBarLayout 通过设置layout_scrollFlags属性可以让子View具有滑动行为。结合布局文件可以看到,我们给LinearLayout设置了三个属性
- scroll:设成这个值的效果就是该View和scrolling view形成一个整体,示例中我们滑动RecyclerView时,LinearLayout也会响应滑动。有一点特别需要我们的注意,为了其他的滚动行为生效,必须同时指定scroll和其他标记。
- enterAlways:设成这个值的效果就是当scrolling view向下滚动时,该View会一起跟着向下滚动,示例图中有所体现。
- enterAlwaysCollapsed:设成这个值的效果就是当我们开始向下滚动scrolling view时,该View会一起跟着滚动直到达到其最小高度。然后当scrolling view滚动至顶部内容完全显示后,再向下滚动scrolling view,该View会继续滚动到完全显示出来。示例图中有所体现
其他可用属性:
- exitUntilCollapsed:设成这个值的效果就是该View离开屏幕时,会被折叠到最小高度。该View已完全折叠后,再向下滚动scrolling view,直到scrolling view顶部的内容完全显示后,该View才会开始向下滚动以显现出来
最后我们还为RecyclerView设置了这样一个属性
app:layout_behavior="@string/appbar_scrolling_view_behavior">
//具体的值是: android.support.design.widget.AppBarLayout$ScrollingViewBehavior
CoordinatorLayout包含的子视图中,带有滚动属性的View必须设置app:layout_behavior属性,AppBarLayout$ScrollingViewBehavior,是AppBarLayout自带一个Behivior
再查看下RecycleView的源码
public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild {}
从上面可以看到RecyclerView其实就是NestedScrollingChild的实现类,这也就解释了嵌套滑动的实现。
CollapsingToolbarLayout 折叠布局
CollapsingToolbarLayout(折叠布局)继承至FrameLayout,通过给它设置layout_scrollFlags,它以控制子View响应layout_behavior事件并作出相应的变化(移除屏幕或固定在屏幕顶端)
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="250dp">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="60dp"
app:expandedTitleMarginStart="50dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="@drawable/bg"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.7" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
- AppBarLayout与Toolbar的高度一定要设置具体值,这是最后展开与固定的值
- CollapsingToolbarLayout的属性设置:layout_scrollFlags一定是必不可少的;contentScrim设置CollapsingToolbarLayout折叠后的背景颜色;expandedTitleMarginStart 设置没有收缩时title向左填充的距离;expandedTitleMarginEnd设置收缩结束时title向左填充的距
- ImageView的属性设置:layout_collapseMode (折叠模式)一定是必不可少的,一共有两种模式。pin:设置为这个模式时,当CollapsingToolbarLayout完全收缩后,Toolbar还可以保留在屏幕上;parallax:设置为这个模式时,在内容滚动时,也可以同时滚动,实现视差滚动效果