MaterialDesign 之 AppBarLayout 與 CollapsingToolbarLayout 的學習

GitLqr發表於2017-06-12

一、簡述

本文要介紹的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>複製程式碼

MaterialDesign 之 AppBarLayout 與 CollapsingToolbarLayout 的學習
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>複製程式碼

MaterialDesign 之 AppBarLayout 與 CollapsingToolbarLayout 的學習
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>複製程式碼

MaterialDesign 之 AppBarLayout 與 CollapsingToolbarLayout 的學習
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>複製程式碼

MaterialDesign 之 AppBarLayout 與 CollapsingToolbarLayout 的學習
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>複製程式碼

MaterialDesign 之 AppBarLayout 與 CollapsingToolbarLayout 的學習
snap

好啦,AppBarLayout對Toolbar的“增強”就差不多這樣了,不過要糾正一點,其實AppBarLayout並不只是對Toolbar"增強",對於其他控制元件也是一樣的,只是AppBarLayout與Toolbar的搭配比較常見而已。下面接著來看看CollapsingToolbarLayout具體可以對Toolbar做到怎樣的“增強”。

3、CollapsingToolbarLayout

CollapsingToolbarLayout對Toolbar的“增強”就是把Toolbar變成可摺疊的,使其具有更多的互動花樣(其實也就是更多的互動動畫),我們先來看看可以實現的效果:

MaterialDesign 之 AppBarLayout 與 CollapsingToolbarLayout 的學習
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的直接子控制元件設定的。先來看看效果怎樣:

MaterialDesign 之 AppBarLayout 與 CollapsingToolbarLayout 的學習

這是預設的效果,可以看到滾動過程中,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>複製程式碼

效果:

MaterialDesign 之 AppBarLayout 與 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以上才能支援,而且,有的國產機對狀態列做了限制,沒辦法生效,比如錘子的系統,狀態列一起是半透明色,且該屬性無法生效,所以,這個效果需視手機及系統版本而定。來看下效果如何:

MaterialDesign 之 AppBarLayout 與 CollapsingToolbarLayout 的學習

呀,馬馬虎虎,不過還差點,需要給圖片“背景”設定視差效果,還有大標題文字底部居中顯示。給圖片“背景”設定視差效果可以通過設定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>複製程式碼

MaterialDesign 之 AppBarLayout 與 CollapsingToolbarLayout 的學習

最後附上Demo連結

github.com/GitLqr/Mate…

相關文章