什么是AppBarLayout
AppBarLayout繼承自LinearLayout,子控件默認(rèn)為豎直方向顯示,可以用它實(shí)現(xiàn)Material Design的Toolbar;它支持滑動(dòng)手勢(shì);它的子控件可以通過(guò)在代碼里調(diào)用setScrollFlags(int)或者在XML里app:layout_scrollFlags來(lái)設(shè)置它的滑動(dòng)手勢(shì)。當(dāng)然實(shí)現(xiàn)這些的前提是它的根布局必須是CoordinatorLayout。這里的滑動(dòng)手勢(shì)可以理解為:當(dāng)某個(gè)可滾動(dòng)View的滾動(dòng)手勢(shì)發(fā)生變化時(shí),AppBarLayout內(nèi)部的子View實(shí)現(xiàn)某種動(dòng)作。
AppBarLayout的子控件不僅僅可以設(shè)置為T(mén)oolbar,也可以包含其他的View。
上面提到使用AppBarLayout的前提是它的根布局必須是CoordinatorLayout,所以我們得先認(rèn)識(shí)一下CoordinatorLayout。
CoordinatorLayout
Google官網(wǎng)對(duì)CoordinatorLayout的介紹:
CoordinatorLayout is a super-powered FrameLayout.
CoordinatorLayout is intended for two primary use cases:
As a top-level application decor or chrome layout
As a container for a specific interaction with one or more child views
由上述的介紹可以知道,CoordinatorLayout繼承自ViewGroup,作為一個(gè)應(yīng)用頂層的裝飾布局,也就是一個(gè)Activity Layout 的最外一層布局;作為一個(gè)或多個(gè)有特定響應(yīng)動(dòng)作的容器;協(xié)調(diào)(Coordinate)其他組件, 實(shí)現(xiàn)聯(lián)動(dòng)。
如何使用AppBarLayout
先看下效果:

可以看到,當(dāng)向上滾動(dòng)時(shí),Toolbar移出屏幕,向下滑動(dòng)時(shí),Toolbar進(jìn)入屏幕。這就是之前的說(shuō)的滑動(dòng)手勢(shì)。
下面我們來(lái)具體看看它的使用,這是布局文件中的代碼:
<?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="wrap_content">
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:title="特戰(zhàn)先驅(qū)"
app:titleTextColor="@android:color/white"
/>
</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"
>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/intro"/>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
上面的代碼中,Toolbar指定了scrollFlags屬性,這個(gè)屬性設(shè)置Toolbar在滾動(dòng)后所做的操作,有以下幾個(gè)值可選:
| Scroll Flag | 作用 |
|---|---|
| scroll | 子View如果設(shè)置layout_scrollFlags屬性的值為scroll,這個(gè)View會(huì)隨著Scrolling View一起滾動(dòng),當(dāng)向上滾動(dòng)的時(shí)候,Toolbar會(huì)滾出屏幕外,如果不設(shè)置,那么Toolbar會(huì)固定不動(dòng)。 |
| enterAlways | 使用這個(gè)flag,當(dāng)Scrolling View 向下滑動(dòng)時(shí),子View 將直接向下滑動(dòng),而不管Scrolling View 是否在滑動(dòng)。注意:要與scroll 搭配使用,否則是不能滑動(dòng)的。(上圖演示的效果,正是scroll和enterAlways兩個(gè)flag同時(shí)使用產(chǎn)生的效果,即向上滾動(dòng),Toolbar滾出屏幕,向下滾動(dòng),Toolbar重新進(jìn)入屏幕)。 |
| enterAlwaysCollapsed | enterAlwaysCollapsed 是對(duì)enterAlways 的補(bǔ)充,當(dāng)Scrolling View 向下滑動(dòng)的時(shí)候,滑動(dòng)View(也就是設(shè)置了enterAlwaysCollapsed 的View)下滑至折疊的高度,當(dāng)Scrolling View 到達(dá)滑動(dòng)范圍的結(jié)束值的時(shí)候,滑動(dòng)View剩下的部分開(kāi)始滑動(dòng)。這個(gè)折疊的高度是通過(guò)View的minimum height (最小高度)指定的。(要配合scroll|enterAlways 一起使用) |
| exitUntilCollapsed | 當(dāng)Scrolling View 滑出屏幕時(shí)(也就時(shí)向上滑動(dòng)時(shí)),滑動(dòng)View先響應(yīng)滑動(dòng)事件,滑動(dòng)至折疊高度,也就是通過(guò)minimum height 設(shè)置的最小高度后,就固定不動(dòng)了,再把滑動(dòng)事件交給 Scrolling view 繼續(xù)滑動(dòng)。 |
| snap | 在滾動(dòng)結(jié)束后,如果view只是部分可見(jiàn),它將滑動(dòng)到最近的邊界。比如,如果view的底部只有25%可見(jiàn),它將滾動(dòng)離開(kāi)屏幕,而如果底部有75%可見(jiàn),它將滾動(dòng)到完全顯示。 |
下面演示設(shè)置scrollFlags為 scroll | enterAlways | enterAlwaysCollapsed 的效果:
修改布局文件:
<?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="wrap_content">
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="140dp"
android:background="@color/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
app:title="特戰(zhàn)先驅(qū)"
app:titleTextColor="@android:color/white"
/>
</android.support.design.widget.AppBarLayout>
...
</android.support.design.widget.CoordinatorLayout>
效果如下:
將Toolbar的高度設(shè)置為某個(gè)固定高度,這里設(shè)置為140dp,設(shè)置,由上圖我們可以看到,當(dāng)向上滾動(dòng)的時(shí)候,Toolbar滾出屏幕,當(dāng)向下滾動(dòng)的時(shí)候,Toolbar進(jìn)入屏幕,顯示折疊高度(最小高度),當(dāng)Scrolling View滾動(dòng)到頂部的時(shí)候,AppBarLayout慢慢展開(kāi)到原來(lái)的高度。
設(shè)置scrollFlags為scroll|exitUntilCollapsed,修改布局代碼:
<?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="wrap_content">
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="140dp"
android:background="@color/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:title="特戰(zhàn)先驅(qū)"
app:titleTextColor="@android:color/white"
/>
</android.support.design.widget.AppBarLayout>
...
</android.support.design.widget.CoordinatorLayout>
演示效果:

可以看到,向上滾動(dòng)時(shí),Toolbar隨著滾動(dòng),但是不會(huì)完全滾出屏幕,而是到達(dá)折疊高度(最小高度),然后一直保持,當(dāng)向下滾動(dòng)的時(shí)候,Scrolling View一直滾動(dòng),當(dāng)Scrolling View滾動(dòng)到頂部時(shí),ToolBar開(kāi)始滾動(dòng),知道展開(kāi)到原來(lái)的高度。
設(shè)置scrollFlags為scroll|snap,修改布局代碼:
<?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="wrap_content">
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="140dp"
android:background="@color/colorPrimary"
app:layout_scrollFlags="scroll|snap"
app:title="特戰(zhàn)先驅(qū)"
app:titleTextColor="@android:color/white"
/>
</android.support.design.widget.AppBarLayout>
...
</android.support.design.widget.CoordinatorLayout>
演示效果:
可以看到,當(dāng)Toolbar展示部分的較大時(shí),此時(shí)放手,它會(huì)自動(dòng)將整個(gè)都展示出來(lái);如果向下拉出一小部分,此時(shí)松手,它會(huì)自動(dòng)將該部分收回去,這和上面說(shuō)到snap的定義一致,滑動(dòng)到最近的邊界。
CollapsingToolbarLayout
學(xué)習(xí)了AppBarLayout和CoordinatorLayout,此時(shí)需要提到一個(gè)非常有用而且高大上的控件CollapsingToolbarLayout,由它的名字我們可以知道,它是一個(gè)折疊的Toolbar布局,先看下演示效果吧:
如何使用CollapsingToolbarLayout呢?只需要將Toolbar使用CollapsingToolbarLayout包裹起來(lái),并且添加多一個(gè)展示背景圖片的ImageView即可,如下是布局文件的代碼:
<?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: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/book"/>
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="特戰(zhàn)先驅(qū)"
app:titleTextColor="@android:color/white"
/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
...
</android.support.design.widget.CoordinatorLayout>
其中l(wèi)ayout_scrollFlags設(shè)置在CollapsingToolbarLayout上而不再是Toolbar上,并且設(shè)置為scroll|exitUntilCollapsed,當(dāng)向上滾動(dòng)到折疊高度時(shí),會(huì)一直保持。
修改展開(kāi)和折疊時(shí)文字的大小和字體
CollapsingToolbarLayout支持對(duì)展開(kāi)時(shí)標(biāo)題和折疊時(shí)標(biāo)題的文字樣式進(jìn)行修改。
需要在style.xml定義樣式:
<!--CollapsingToolbarLayout展開(kāi)時(shí)標(biāo)題文字樣式-->
<style name="ExpandedTitleTextStyle" parent="TextAppearance.AppCompat.Title">
<item name="android:textSize">30sp</item>
<item name="android:textColor">#fff</item>
</style>
<!--CollapsingToolbarLayout折疊時(shí)標(biāo)題文字樣式-->
<style name="CollapsedTitleTextStyle" parent="TextAppearance.AppCompat.Title">
<item name="android:textSize">16sp</item>
<item name="android:textColor">#f00</item>
</style>
指定CollapsingToolbarLayout折疊和展開(kāi)的標(biāo)題樣式:
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:collapsedTitleTextAppearance="@style/CollapsedTitleTextStyle"
app:expandedTitleTextAppearance="@style/ExpandedTitleTextStyle"
>
...
</android.support.design.widget.CollapsingToolbarLayout>
修改后,效果如下:
到此為止,關(guān)于AppBarLayout、CoordinatorLayout和CollapsingToolbarLayout的使用,我們就基本掌握了。需要源碼的可以查看: