Android CoordinatorLayout 协调布局

本篇主要介绍一下四个布局控件,他们之间相互配合可以创造出流畅的动画,实现各种复杂的效果

  • CoordinatorLayout
  • AppBarLayout
  • CollapsingToolbarLayout
  • ToolBar

CoordinatorLayout

CoordinatorLayout 是功能强大的FrameLayout。

CoordinatorLayout主要有两个用途

  1. 用作应用的顶层布局管理器,作为界面其他控件的父容器
  2. 作为与一个或多个子视图进行特定交互的容器

通过为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>

效果如下:

Android 协调布局吸顶渐变 安卓协调布局_xml

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>

Android 协调布局吸顶渐变 安卓协调布局_android_02

  1. AppBarLayout与Toolbar的高度一定要设置具体值,这是最后展开与固定的值
  2. CollapsingToolbarLayout的属性设置:layout_scrollFlags一定是必不可少的;contentScrim设置CollapsingToolbarLayout折叠后的背景颜色;expandedTitleMarginStart 设置没有收缩时title向左填充的距离;expandedTitleMarginEnd设置收缩结束时title向左填充的距
  3. ImageView的属性设置:layout_collapseMode (折叠模式)一定是必不可少的,一共有两种模式。pin:设置为这个模式时,当CollapsingToolbarLayout完全收缩后,Toolbar还可以保留在屏幕上;parallax:设置为这个模式时,在内容滚动时,也可以同时滚动,实现视差滚动效果

参考: