support design安卓开源框架CollapsingToolbarLayout

MaterialDesign之AppBarLayout与Coll

2017-06-13  本文已影响1218人  GitLqr

一、简述

本文要介绍的AppBarLayout与CollapsingToolbarLayout均是随MaterialDesign出现的新控件,两者的作用呢,可以说就是为了“增强”Toolbar的吧,它们的出现使得Toolbar不再只是那个木讷的"ActionBar",而是一个真正有灵性,有活力的APP工具条。下面就来看看它们是怎么使用的吧。

二、使用

1、CoordinatorLayout

在使用AppBarLayout与CollapsingToolbarLayout之前,先来说说这个CoordinatorLayout。CoordinatorLayout直译为“协调布局”,顾名思义,它就是用来协调子布局及控件的,要使用它,则必须把它设置为整个布局的根,同时,通过对“特殊子控件”设置app:appbar_scrolling_view_behavior属性的值,进而来协调子控件在整个布局中的显示位置。本文不对其进行深入讲解,我们这里只需知道,要使用AppbarLayout来“增强”Toolbar,就需要用到CoordinatorLayout即可。CoordinatorLayout的使用示例代码:

<?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="256dp">
        ...
    </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/webview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    </android.support.v4.widget.NestedScrollView>


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

从上面的代码中,可以知道,这里只对NestedScrollView控件设置了app:appbar_scrolling_view_behavior属性,没错,NestedScrollView是上面说到的“特殊子控件”,像这样的“特殊子控件”有3个,分别是RecyclerView、ViewPager、NestedScrollView,它们的使用基本是一样的,app:appbar_scrolling_view_behavior属性也只对这3个“特殊子控件”有效。对于这个NestedScrollView,你可以认为,它就是ScrollView的增强版而已。好了,下面就开始介绍本文的主角。

2、AppBarLayout

下面是官方文档中对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来建立。

结合上面CoordinatorLayout部分中贴出的代码,这段描述的后半段是不难理解的,而比较难理解的应该是layout_scrollFlags属性,描述中的scrolling view就是上面所说的“特殊子控件”。要牢记,描述中说的是对AppbarLayout的直接子控件设置layout_scrollFlags属性,下面来看看都有哪些ayout_scrollFlags属性:

scrollFlags的属性值 作用
scroll 让AppBarLayout与scrolling view合为一体,当scrolling view滚动时,AppBarLayout也跟着一起滚动。这是“增强”Toolbar的一个必需取值,可以跟其他值一起使用,从而实现不同的“增强”效果。单独使用scroll的话,其效果就类似给ListView加了一个HeaderView。
<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="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:title="CSDN_LQR"
            app:layout_scrollFlags="scroll"
            app:titleTextColor="@android:color/white"/>

    </android.support.design.widget.AppBarLayout>
    ...
</android.support.design.widget.CoordinatorLayout>
scroll
scrollFlags的属性值 作用
scroll | enterAlways 当scrolling view向上滚动时,AppBarLayout也跟着一起滚出屏幕,一旦scrolling view向下滚动,AppBarLayout也跟着一起滚入屏幕。
<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="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_scrollFlags="scroll|enterAlways"
            app:title="CSDN_LQR"
            app:titleTextColor="@android:color/white"/>

    </android.support.design.widget.AppBarLayout>
    ...
</android.support.design.widget.CoordinatorLayout>
enterAlways
scrollFlags的属性值 作用
scroll | enterAlways | enterAlwaysCollapsed 当scrolling view向上滚动时,AppBarLayout也跟着一起滚出屏幕,一旦scrolling view向下滚动,AppBarLayout便先慢慢滚动到折叠高度(即最小高度),直到scrolling view向下滚动到最顶部时,AppBarLayout再先慢慢滚动到原来的高度(此时scrolling view也会再次和AppBarLayout一起滚动)。
<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="wrap_content"
        android:minHeight="?attr/actionBarSize">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="150dp"
            app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
            app:title="CSDN_LQR"
            app:titleTextColor="@android:color/white"/>

    </android.support.design.widget.AppBarLayout>
    ...
</android.support.design.widget.CoordinatorLayout>
enterAlwaysCollapsed
scrollFlags的属性值 作用
scroll | exitUntilCollapsed 当scrolling view向上滚动时,AppBarLayout也跟着一起滚出屏幕,直到达到了折叠高度(即最小高度),此时AppBarLayout不再滚动,也就是不完全滚出屏幕,而当scrolling view向下滚动到最顶部时,AppBarLayout才会再随scrolling view一起滚动,直到原来的高度。
<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="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="150dp"
            android:minHeight="?attr/actionBarSize"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:title="CSDN_LQR"
            app:titleTextColor="@android:color/white"/>

    </android.support.design.widget.AppBarLayout>
    ...
</android.support.design.widget.CoordinatorLayout>
exitUntilCollapsed
scrollFlags的属性值 作用
scroll | snap snap有仓促的意思,效果同它的意思一样,当scrolling view处于无法再向下滚动的状态时(即已经到顶部了),此时向上滚动scrolling view,AppBarLayout将一次全部滚出屏幕,或向下滚动scrolling view,AppBarLayout将一次全部滚入屏幕。有一种引力的感觉。
<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="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="150dp"
            android:minHeight="?attr/actionBarSize"
            app:layout_scrollFlags="scroll|snap"
            app:title="CSDN_LQR"
            app:titleTextColor="@android:color/white"/>

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

好啦,AppBarLayout对Toolbar的“增强”就差不多这样了,不过要纠正一点,其实AppBarLayout并不只是对Toolbar"增强",对于其他控件也是一样的,只是AppBarLayout与Toolbar的搭配比较常见而已。下面接着来看看CollapsingToolbarLayout具体可以对Toolbar做到怎样的“增强”。

3、CollapsingToolbarLayout

CollapsingToolbarLayout对Toolbar的“增强”就是把Toolbar变成可折叠的,使其具有更多的交互花样(其实也就是更多的交互动画),我们先来看看可以实现的效果:

CollapsingToolbarLayout

要实现上图的效果,需要跟AppBarLayout一起使用,CollapsingToolbarLayout的使用很简单,直接包裹Toolbar即可,其中可以增加一个ImageView控件来作为CollapsingToolbarLayout的“背景”,其实CollapsingToolbarLayout本身是一个FrameLayout,所以其子控件的摆放就是从左上角开始,一个个叠加起来。不过,其中的Toolbar默认一开始是隐藏的。

<?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="256dp">

        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:src="@mipmap/palette"/>

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:title="CSDN_LQR"
                app:titleTextColor="@android:color/white"/>
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>
    ...
</android.support.design.widget.CoordinatorLayout>

这代码中有个细节需要注意一下,你可以发现,代码中不再对Toolbar设置app:layout_scrollFlags属性,而是给CollapsingToolbarLayout控件设置了。这不奇怪,因为上面已经说了,app:layout_scrollFlags属性是对AppBarLayout的直接子控件设置的。先来看看效果怎样:

这是默认的效果,可以看到滚动过程中,ImageView和大标题一起向上或向下滚动,其实这个过程中,只有当CollapsingToolbarLayout折叠时,Toolbar才会显示出来,大标题执行了缩放、位置和透明等动画,而Toolbar执行透明动画,两标题重合或分离,看起来好像就只有一个标题一样。此外,上面的布局代码中是有给Toolbar设置样式的,但并没有起作用。CollapsingToolbarLayout提供了文字样式属性,可以分别对大标题(展开标题)与小标题(折叠标题)的文字样式进行设置。

style.xml中文字样式代码如下:

<!--CollapsingToolbarLayout展开时标题文字样式-->
<style name="ExpandedTitleTextAppearance" parent="TextAppearance.AppCompat.Title">
    <item name="android:textSize">30sp</item>
    <item name="android:textColor">#fff</item>
</style>
<!--CollapsingToolbarLayout折叠时标题文字样式-->
<style name="CollapsedTitleTextAppearance" parent="TextAppearance.AppCompat.Title">
    <item name="android:textSize">15sp</item>
    <item name="android:textColor">#000</item>
</style>

对CollapsingToolbarLayout分别设置展开标题样式与折叠标题样式

<android.support.design.widget.CollapsingToolbarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_scrollFlags="scroll|exitUntilCollapsed"
    app:collapsedTitleTextAppearance="@style/CollapsedTitleTextAppearance"
    app:expandedTitleTextAppearance="@style/ExpandedTitleTextAppearance"
    >
    ...
</android.support.design.widget.CollapsingToolbarLayout>

效果:

这样还不够,如果想在CollapsingToolbarLayout折叠时,背景变为纯色、状态栏也一起变色的话,可以通过如下代码设置:

<android.support.design.widget.CollapsingToolbarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_scrollFlags="scroll|exitUntilCollapsed"
    app:collapsedTitleTextAppearance="@style/CollapsedTitleTextAppearance"
    app:expandedTitleTextAppearance="@style/ExpandedTitleTextAppearance"
    app:contentScrim="?attr/colorPrimary"
    app:statusBarScrim="?attr/colorPrimaryDark"
    >
    ...
</android.support.design.widget.CollapsingToolbarLayout>

其中contentScrim设置的是折叠时,CollapsingToolbarLayout的背景色。statusBarScrim设置的是折叠时,状态栏的颜色,可以达到沉浸式的效果,不过这个属性需要Android 5.0以上才能支持,而且,有的国产机对状态栏做了限制,没办法生效,比如锤子的系统,状态栏一起是半透明色,且该属性无法生效,所以,这个效果需视手机及系统版本而定。来看下效果如何:

呀,马马虎虎,不过还差点,需要给图片“背景”设置视差效果,还有大标题文字底部居中显示。给图片“背景”设置视差效果可以通过设置app:layout_collapseMode属性来完成,这个属性只要是CollapsingToolbarLayout的子控件就有,有三种取值,分别是:none、pin、parallax。其中parallax的效果是在CollapsingToolbarLayout折叠时,此布局(或控件)会有视差折叠效果;pin的效果是在CollapsingToolbarLayout折叠后,此布局(或控件)将固定在顶部。none是默认值,即没有效果,实话说,我感觉pin跟none没什么区别(如果觉得我说的不对,请不吝赐教)。至于标题的位置,可以通过app:collapsedTitleGravity和app:collapsedTitleGravity来配置,用法跟layout_gravity一样,就不说了,贴下代码,随便看下效果。

<android.support.design.widget.CollapsingToolbarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:collapsedTitleTextAppearance="@style/CollapsedTitleTextAppearance"
    app:contentScrim="?attr/colorPrimary"
    app:expandedTitleTextAppearance="@style/ExpandedTitleTextAppearance"
    app:layout_scrollFlags="scroll|exitUntilCollapsed"
    app:statusBarScrim="?attr/colorPrimaryDark"
    app:collapsedTitleGravity="start"
    app:expandedTitleGravity="center_horizontal|bottom" >

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:src="@mipmap/palette"
        app:layout_collapseMode="parallax"/>

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:title="CSDN_LQR"
        app:titleTextColor="@android:color/white"
        app:layout_collapseMode="pin"/>
</android.support.design.widget.CollapsingToolbarLayout>

最后附上Demo链接

https://github.com/GitLqr/MaterialDesignDemo

上一篇下一篇

猜你喜欢

热点阅读