Android Material Design之CoordinatorLayout+AppBarLayout实现上滑隐藏

1 前言

今天想总结一下Material Design的两个控件CoordinatorLayout+AppBarLayout,主要是AppBarLayout。结合着两个控件,可以实现一些炫酷的效果。如下:
Android Material Design之CoordinatorLayout+AppBarLayout实现上滑隐藏_第1张图片
可以看到我们的Toolbar会随着我们的RecyclerView 滚动而发生隐藏或者展开。效果还是比较炫的!

2 AppBarLayout

我们查看源码,发现APPBarLayout 继承 LinearLayout,并且是一个竖直方向上的LinearLayout,其实它最主要的作用就是当某个可滚动的View发生滚动时(例如RecyclerView 发生滚动),其内部子View如果跟着一起发生动作,这动作系统为我们提供了几种。

请注意:上面提到的某个可滚动View,可以理解为某个ScrollView,ListView等。怎么理解上面的话呢?就是说,当某个ScrollView发生滚动时,你可以定制你的“顶部栏”应该执行哪些动作(如跟着一起滚动、保持不动等等)。那某个可移动的View到底是哪个可移动的View呢?这是由你自己指定的!如何指定,我们后面说。

我们先来看下刚刚的例子。
布局文件:

"1.0" encoding="utf-8"?>
.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_about"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".module.activity.AboutActivity">

    .support.design.widget.AppBarLayout
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        .support.v7.widget.Toolbar
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="?android:attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:id="@+id/toolbar"
            android:theme="@style/Theme.Toolbar"
            app:popupTheme="@style/ToolbarPopupTheme"
            app:layout_scrollFlags="scroll|enterAlways">
        .support.v7.widget.Toolbar>

    .support.design.widget.AppBarLayout>

    .support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/recycler_view"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
    .support.v7.widget.RecyclerView>

.support.design.widget.CoordinatorLayout>

我们先来看AppBarLayout,我们在里面指定了一个ToolBar,在ToolBar中我们设置了Theme,但是有一项是这样的:app:layout_scrollFlags="scroll|enterAlways"
这里layout_scrollFlags就是我们为AppBarLayout子View设置的动作,scroll:值设为scroll的View会跟随滚动事件一起发生移动。enterAlways:值设为enterAlways的View,当ScrollView往下移动时,该View会直接往下滚动。而不用考虑ScrollView是否在滚动。

一般说来,layout_scrollFlags可以为以下几种:

1 scroll:值设为scroll的View会跟随滚动事件一起发生移动。

什么意思呢?简单的说,就是当指定的ScrollView发生滚动时,该View也跟随一起滚动,就好像这个View也是属于这个ScrollView一样。
例如:

布局文件:

    .support.design.widget.AppBarLayout
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        .support.v7.widget.Toolbar
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="?android:attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:id="@+id/toolbar"
            android:theme="@style/Theme.Toolbar"
            app:popupTheme="@style/ToolbarPopupTheme"
            app:layout_scrollFlags="scroll">
        .support.v7.widget.Toolbar>

    .support.design.widget.AppBarLayout>

2 enterAlways:值设为enterAlways的View,当ScrollView往下滚动时,该View会直接往下滚动。而不用考虑ScrollView是否在滚动。

这种效果如下:
Android Material Design之CoordinatorLayout+AppBarLayout实现上滑隐藏_第2张图片

布局文件

.support.design.widget.AppBarLayout
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        .support.v7.widget.Toolbar
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="?android:attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:id="@+id/toolbar"
            android:theme="@style/Theme.Toolbar"
            app:popupTheme="@style/ToolbarPopupTheme"
            app:layout_scrollFlags="scroll|enterAlways">
        .support.v7.widget.Toolbar>

    .support.design.widget.AppBarLayout>

这个就是我们最开始的效果,它与 1 的不同就是:只要ScrollView在网下滚动,那么没有滚动到头,APPBarLayout中的子View也会跟着一起滚动,1 是只有往下滚动到头了APPBarLayout中的子View才会跟着一起滚动。

3 exitUntilCollapsed:值设为exitUntilCollapsed的View,当这个View要往上逐渐“消逝”时,会一直往上滑动,直到剩下的的高度达到它的最小高度后,再响应ScrollView的内部滑动事件。

怎么理解呢?简单解释:在ScrollView往上滑动时,首先是APPBarLayout中的子View把滑动事件“夺走”,由View去执行滑动,直到滑动最小高度后,把这个滑动事件“还”回去,让ScrollView内部去上滑。
我们给ToolBar设定一个最小高度,先看布局文件:

.support.design.widget.AppBarLayout
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        .support.v7.widget.Toolbar
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:minHeight="?android:attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:id="@+id/toolbar"
            android:theme="@style/Theme.Toolbar"
            app:popupTheme="@style/ToolbarPopupTheme"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">
        .support.v7.widget.Toolbar>

    .support.design.widget.AppBarLayout>

效果如下:

4 enterAlwaysCollapsed:是enterAlways的附加选项,一般跟enterAlways一起使用,它是指,View在往下“出现”的时候,首先是enterAlways效果,当View的高度达到最小高度时,View就暂时不去往下滚动,直到ScrollView滑动到顶部不再滑动时,View再继续往下滑动,直到滑到View的顶部结束。

还是先来看布局吧:

    .support.design.widget.AppBarLayout
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        .support.v7.widget.Toolbar
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:minHeight="?android:attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:id="@+id/toolbar"
            android:theme="@style/Theme.Toolbar"
            app:popupTheme="@style/ToolbarPopupTheme"
            app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed">
        .support.v7.widget.Toolbar>

    .support.design.widget.AppBarLayout>

效果如下:
Android Material Design之CoordinatorLayout+AppBarLayout实现上滑隐藏_第3张图片

注意观察,当我最开始向下滑动时,没有ToolBar开始展开到最小宽度,然后我再向下滚动到RecyclerView
的顶部时,ToolBar就又接着展开到200dp了。

3 将AppBarLayout与“ScrollView”关联起来

我们一直在说“当ScrollView发生滚动时”,那么怎么将AppBarLayout与ScrollView关联起来呢?这里需要用到另一个控件了:CoordinatorLayout,关于CoordinatorLayout,我们这里只是简单的介绍下,后面会单独写一篇来介绍。
简单来说CoordinatorLayout是组织它众多子view之间互相协作的一个ViewGroup。在这里就是组织我们的RecyclerView与APPBarLayout 协调的。我们看我们最开始的布局:

"1.0" encoding="utf-8"?>
.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_about"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".module.activity.AboutActivity">

    .support.design.widget.AppBarLayout
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        .support.v7.widget.Toolbar
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:minHeight="?android:attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:id="@+id/toolbar"
            android:theme="@style/Theme.Toolbar"
            app:popupTheme="@style/ToolbarPopupTheme"
            app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed">
        .support.v7.widget.Toolbar>

    .support.design.widget.AppBarLayout>

    .support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/recycler_view"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
    .support.v7.widget.RecyclerView>

.support.design.widget.CoordinatorLayout>

发现没?对于RecyclerView我们多了这样一行:

app:layout_behavior="@string/appbar_scrolling_view_behavior">

它就是指定behavior的,appbar_scrolling_view_behavior对应的类的名称是:android.support.design.widget.AppBarLayout$ScrollingViewBehavior感兴趣的可以去分析源码。

这样指定了之后,我们的RecyclerView就和APPBarLayout联系起来了。至于什么事behavior, Behavior就是执行你定制的动作,注意behavior只有是CoordinatorLayout的直接子View才有意义。我们会在后面详细分析CoordinatorLayout与其Behavior的,这里只需要知道怎么用就行了。

你可能感兴趣的:(android,UI开发)