玩转AppBarLayout

本篇文章会从官方文档出发,从基本使用姿势到工作原理,试图把AppBarLayout彻底讲明白。如有叙述不清晰或是不准确的地方希望大家可以指出,感谢各位:)
阅读本文最好对CoordinatorLayout和Behavior有一定的了解,还不太熟悉的小伙伴请戳http://www.jianshu.com/p/b81f5e0d3241

从是什么开始

首先,我们来看看官方文档中对AppBarLayout的描述:

AppBarLayout是一个垂直的LinearLayout,实现了Material Design中app bar的scrolling gestures特性。AppBarLayout的子View应该声明想要具有的“滚动行为”,这可以通过layout_scrollFlags属性或是setScrollFlags()方法来指定。
AppBarLayout只有作为CoordinatorLayout的直接子View时才能正常工作,
为了让AppBarLayout能够知道何时滚动其子View,我们还应该在CoordinatorLayout布局中提供一个可滚动View,我们称之为scrolling view。scrolling view和AppBarLayout之间的关联,通过将scrolling view的Behavior设为AppBarLayout.ScrollingViewBehavior来建立。

根据上面的描述我们可以知道,AppBarLayout主要用来实现这样的功能:当位于同一父容器中的可滚动View发生滚动时,AppBarLayout会根据子View声明的滚动行为来对其子View进行相应的滚动。这也就是上面描述中提到的scrolling gestures。这么说可能还不够形象,那么我们下面通过实际例子来体会一下。

app bar

在介绍scrolling gestures之前,我们先来简单提下app bar的概念。app bar的示意图如下:

《玩转AppBarLayout》 app bar示意图

app bar是Material Design中的一个概念,我们可以把它看做是一种ToolBar。我们把TooBar套上一层AppBarLayout,就能把顶部栏玩出各种花样,比如前面我们提到的scrolling gestures。下面我们来通过一个简单地例子,看看究竟什么是scrolling gestures。

scrolling gestures

先看个动图感受下:

《玩转AppBarLayout》 scrolling_gesture_demo

当我们向上滚动可滚动View时,ToolBar会消失;当我们再向下滚动可滚动View时,ToolBar又会随之出现。这就是一个简单地scrolling gesture的示例。实际上,ToolBar本身可没有这个能耐,我们通过为它包上一层AppBarLayout,并为ToolBar指定一个滚动行为,就能够让ToolBar随着下面的可滚动View的滚动而发生滚动。可滚动View也就是我们上面提到的scrolling view。

现在,我们对AppBarLayout已经建立起了感性认识,接下来我们来详细介绍下AppBarLayout的用法。

玩转AppBarLayout

我们就以上面的简单demo为例子,介绍下AppBarLayout的用法。

XML布局文件

上面例子的XML布局文件如下:

<?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:id="@+id/coordinator"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?android:attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll" />
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <WebView
            android:id="@+id/web_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        </WebView>
    </android.support.v4.widget.NestedScrollView>

</android.support.design.widget.CoordinatorLayout>

在上面的布局文件中,NestedScrollView充当了scrolling view的角色,实际上scrolling view需要支持嵌套滚动,通常我们使用NestedScrollView、RecyclerView等已经实现了嵌套滚动的UI控件。关于嵌套滚动,后面的文章中我们会做出详细介绍。

我们注意到,上面Toolbar的layout_scrollFlags属性被设置为了“scroll”,意思是Toolbar会随则scrolling view的滚动而发生滚动,就像我们上面看到的那样。通过为AppBarLayout的子View设定不同的layout_scrollFlags值,可以定义不同的滚动行为,下面我们看一下,layout_scrollFlags的取值有哪几种。

layout_scrollFlags

根据官方文档,layout_scrollFlags的取值可以为以下几种。

scroll

设成这个值的效果就好比本View和scrolling view是“一体”的。具体示例我们在上面已经给出。有一点特别需要我们的注意,为了其他的滚动行为生效,必须同时指定scroll和相应的标记,比如我们想要exitUntilCollapsed所表现的滚动行为,必须将layout_scrollFlags指定为“scroll|exitUntilCollapsed”。

exitUntilCollapsed

当本View离开屏幕时,会被“折叠”直到达到其最小高度。我们可以这样理解这个效果:当我们开始向上滚动scrolling view时,本View会先接管滚动事件,这样本View会先进行滚动,直到滚动到了最小高度(折叠了),scrolling view才开始实际滚动。而当本View已完全折叠后,再向下滚动scrolling view,直到scrolling view顶部的内容完全显示后,本View才会开始向下滚动以显现出来。Demo如下:(为了演示效果,把ToolBar高度设为了150dp)

《玩转AppBarLayout》 exitUntilCollapsed

enterAlways

当scrolling view向下滚动时,本View会一起跟着向下滚动。实际上就好比我们同时对scrolling view和本View进行向下滚动,具体效果如下图所示:

《玩转AppBarLayout》 enterAlways

仔细观察上图可以发现,与exitUntilCollapsed不同,当scrolling view一开始滚动,ToolBar便已开始跟着滚动,而无需scrolling view将其内容滚动到顶部。

enterAlwaysCollapsed

从名字上就可以看出,这是在enterAlways的基础上,加上了“折叠”的效果。当我们开始向下滚动scrolling view时,本View会一起跟着滚动直到达到其“折叠高度”(即最小高度)。然后当scrolling view滚动至顶部内容完全显示后,再向下滚动scrolling view,本View会继续滚动到完全显示出来。具体效果如下:

《玩转AppBarLayout》 enterAlwaysCollapsed

注意,要达到上图所示效果,需要把layout_scrollFlags指定为“scroll|enterAlways|enterAlwaysCollapsed”。

snap

在一次滚动结束时,本View很可能只处于“部分显示”的状态,加上这个标记能够达到“要么完全隐藏,要么完全显示”的效果。

到了这里,我们就把AppBarLayout能够实现的滚动行为介绍完毕了,很简单有木有。接下来我们再来介绍一下AppBarLayout的一个亲密朋友——CollapsingToolbarLayout。

CollapsingToolbarLayout

按照惯例,先贴一下官方文档对其做的介绍:

CollapsingToolbarLayout通常用来在布局中包裹一个Toolbar,以实现具有“折叠效果“”的顶部栏。它需要是AppBarLayout的直接子View,这样才能发挥出效果。CollapsingToolbarLayout包含以下特性:

  1. Collasping title(可折叠标题):当布局完全可见时,这个标题比较大;当折叠起来时,标题也会变小。标题的外观可以通过expandedTextAppearance和collapsedTextAppearance属性来调整。
  2. Content scrim(内容纱布):根据CollapsingToolbarLayout是否滚动到一个临界点,内容纱布会显示或隐藏。可以通过setContentScrim(Drawable)来设置内容纱布。
  3. Status bar scrim(状态栏纱布):也是根据是否滚动到临界点,来决定是否显示。可以通过setStatusBarScrim(Drawable)方法来设置。这个特性只有在Android5.0及其以上版本,我们设置fitSystemWindows为ture时才能生效。
  4. Parallax scrolling children(视差滚动子View):子View可以选择以“视差”的方式来进行滚动。(视觉效果上就是子View滚动的比其他View稍微慢些)
  5. Pinned position children:子View可以选择固定在某一位置上。

上面的描述有些抽象,实际上对于Content scrim、Status bar scrim我们可以暂时予以忽略,只要留个大概印象待以后需要时再查阅相关资料即可。下面我们通过一个常见的例子介绍下CollapsingToolbarLayout的基本使用姿势。

如何使用CollapsingToolbarLayout

先看效果:

《玩转AppBarLayout》 collapsingToolbar

我们可以看到,顶部栏会随着scrolling view向上滚动而折叠。接下来看一下这个效果究竟是怎样实现的。

XML布局文件
<?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:id="@+id/coordinator"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="256dp"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:expandedTitleMarginEnd="50dp"
            app:expandedTitleMarginStart="50dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">
            <ImageView
                android:src="@mipmap/ic_launcher"
                android:id="@+id/image"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax" />
            <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.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <WebView
            android:id="@+id/web_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        </WebView>
 </android.support.v4.widget.NestedScrollView>

</android.support.design.widget.CoordinatorLayout>

我们在XML文件中为CollapsingToolbarLayout的layout_scrollFlags指定为“scroll|exitUntilCollapsed”,这样便实现了向上滚动scrolling view时的折叠效果。
CollapsingToolbarLayout本质上是一个FrameLayout。我们在布局文件中为它指定了两个子View,分别是ImageView和Toolbar。ImageView的layout_collapseMode属性设为了parallax,也就是我们前面介绍的视差滚动;而Toolbar的layout_collaspeMode设为了pin,也就是Toolbar会始终固定在顶部。

contentScrim

在上图中,我们看到Toolbar的背景一直都是我们指定的图片,即时图片向上滚动到消失后也是这样。那么可不可以让图片完全消失后,Toolbar显示一个另外的背景呢?答案是肯定的,只要使用我们上面提到的“内容纱布”即可。还记得我们上面关于内容纱布的介绍吗?当CollapsingToolbarLayout滚动到一个临界位置,内容纱布就会显现出来,我们通过一个例子感受下。

我们把CollapsingToolbarLayout的contentScrim属性指定为”?attr/colorPrimary”后,再运行一下Demo,可以得到如下效果:

《玩转AppBarLayout》 contentScrim

我们可以看到,当CollapsingToolbarLayout完全折叠后,ToolBar的背景变为了黑色,好像盖上了一层布,所以这个属性叫做“内容纱布”。这里我们发现,只有CollapsingToolbarLayout滚动到折叠后,内容纱布才显现出来,也就是说,默认的临界位置就是滚动到折叠。

对AppBarLayout的介绍就到这里了,后续的篇章中我们还会介绍其他常用的Material Design风格控件以及相关的机制,敬请关注:)。

**长按或扫描二维码关注我们,让您利用每天等地铁的时间就能学会怎样写出优质app。 **

《玩转AppBarLayout》

    原文作者:absfree
    原文地址: https://www.jianshu.com/p/9e87e5912199
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞