Android Design Support Library系列之八:AppBarLayout、CollapsingToolbarLayout

使用前添加依賴:

compile 'com.android.support:design:25.3.1'

一、AppBarLayout

官方文檔

1、介紹

1)AppBarLayout繼承自LinearLayout,是一個垂直的線性布局
2)AppBarLayout內的子View可以通過設置app:layout_scrollFlags=" "屬性來決定自己執行何種動作.

使用前提

1)需要使用CoordinatorLayout作為父容器,如果使用其它的ViewGroup,AppBarLayout的大部分功能將無法生效.
2)AppBarLayout同時也需要一個具有單獨滾動能力的兄弟節點(實現了NestedScrollingChild接口)才能發揮其功能。

AppBarLayout和其兄弟節點綁定是通過:

AppBarLayout.ScrollingViewBehavior行為類

2、簡單使用

<?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.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/text" />
    </android.support.v4.widget.NestedScrollView>

    <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"
            app:layout_scrollFlags="scroll"
            app:title="一生所愛"
            app:titleTextColor="#ffffff" />
    </android.support.design.widget.AppBarLayout>

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

效果圖:


可以看見,被AppBarLayout包裹的Toolbar在NestedScrollView滾動時跟隨著一起滾動,這就是AppBarLayout的作用了。

我們可以通過為AppBarLayout內的子View設置app:layout_scrollFlags=" "屬性來決定------當AppBarLayout的兄弟節點滾動狀態發生變化時-------AppBarLayout內的子View執行何種動作.

3、app:layout_scrollFlags屬性值

(1)scroll--------該View隨滾動事件一起發生滾動,就好像RecyclerView滾動時,其Header也一起滾動,沒有設置這個flag的子View將被固定在屏幕頂部
注意:
如果使用了下面其它幾個值,必定要使用這個值才能起作用;
如果AppBarLayout中某個子View前面的任何其它子View沒有設置這個值,那么該View的這條屬性將失去作用.

(2)enterAlways--------當兄弟節點往下滾動時,該View會直接往下滾動,而不用考慮兄弟節點是否在滾動,相當于快速返回模式.
和scroll一起使用:app:layout_scrollFlags="scroll|enterAlways"

(3)enterAlwaysCollapsed--------enterAlways的附加選項,一般跟enterAlways一起使用,首先觸發enterAlways快速返回效果,但并不會完全快速返回,當View快速返回的高度達到最小高度時,View就暫時不去往下滾動,直到兄弟節點滑動到頂部時,View再繼續往下滑動,也就是有保留的快速返回.

    <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="233dp"
            android:minHeight="?android:attr/actionBarSize"
            app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
            app:title="一生所愛"
            app:titleTextColor="#ffffff" />
    </android.support.design.widget.AppBarLayout>


(4)exitUntilCollapsed--------當兄弟節點向上滾動時,該View向上滾動逐漸消失時,會保留一個最小高度,當該View剩下的的高度達到它的最小高度后,不再響應滾動事件,也就是有保留的向上滾動.

    <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="233dp"
            android:minHeight="?android:attr/actionBarSize"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:title="一生所愛"
            app:titleTextColor="#ffffff" />
    </android.support.design.widget.AppBarLayout>

(5)snap--------和scroll一起使用
使用了snap后,該View要么不顯示,要么全部顯示
【i】當兄弟節點向上滾動,該View消失的高度不足本身一半,松開手指停止滾動后,該View會彈回來,大于一半該View會自動滾動消失
【ii】當兄弟節點向下滾動,該View顯示的高度不足本身一半,松開手指停止滾動后,該View會彈回去,大于一半該View會自動滾動顯示完全

app:layout_scrollFlags="scroll|snap"

有彈性的快速返回與消失


4、簡單介紹實現原理

你肯定會很好奇這種效果是怎么實現的,如果你對CoordinatorLayout以及Behavior有所了解,或者你看過我的另外一篇文章Android Design Support Library系列之七:CoordinatorLayout,你應該知道一些實現細節了。
(1)在AppBarLayout中定義好了2個Behavior:AppBarLayout.Behavior、AppBarLayout.ScrollingViewBehavior
(2)AppBarLayout.Behavior是給AppBarLayout自己使用的,已經通過注解的方式給AppBarLayout使用了:

@CoordinatorLayout.DefaultBehavior(AppBarLayout.Behavior.class)
public class AppBarLayout extends LinearLayout {
  ......
}

在AppBarLayout.Behavior中,AppBarLayout通過NestedScroll一系列方法決定了其兄弟節點滾動狀態變化時,AppBarLayout內子View執行何種動作
(3)AppBarLayout.ScrollingViewBehavior是給AppBarLayout兄弟節點使用的,我們一般通過在其兄弟節點上添加下面這條屬性使用該Behavior:

app:layout_behavior="@string/appbar_scrolling_view_behavior"

AppBarLayout.ScrollingViewBehavior中:

public static class ScrollingViewBehavior extends HeaderScrollingViewBehavior {
  ......
        @Override
        public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
            // We depend on any AppBarLayouts
            return dependency instanceof AppBarLayout;
        }

        @Override
        public boolean onDependentViewChanged(CoordinatorLayout parent, View child,
                View dependency) {
            offsetChildAsNeeded(parent, child, dependency);
            return false;
        }
  ......
}

其兄弟節點使用了該Behavior后,和AppBarLayout就存在依賴關系了.
(i)這也解釋了為什么上面我的NestedScrollView放在AppBarLayout上面,結果效果圖中NestedScrollView在AppBarLayout下方,這是因為在依賴關系中:不管child(NestedScrollView)的順序如何,你的child將總是在所依賴的dependency(AppBarLayout)放置之后才會被放置。
(ii)同時,在AppBarLayout狀態發生變化時(位置、大小等),NestedScrollView也會執行相應變化:

offsetChildAsNeeded(parent, child, dependency);

二、CollapsingToolbarLayout

官方文檔

1、介紹

1)CollapsingToolbarLayout繼承自FrameLayout.
2)CollapsingToolbarLayout通常用來在布局中包裹一個Toolbar,以實現具有“折疊效果“的頂部欄.
3)CollapsingToolbarLayout必須作為AppBarLayout的直接子View使用才能發揮出效果.

2、效果圖

3、主要功能

(1)Collapsing title(折疊title):當CollapsingToolbarLayout布局內容全部可見時,title 是最大的,當AppBarLayout 兄弟節點向上滾動,CollapsingToolbarLayout布局內容開始滑出屏幕時,title 將變得越來越小
Tips:
a)為CollapsingToolbarLayout設置title

app:title=" "屬性
或者setTitle(CharSequence) 方法

b)當CollapsingToolbarLayout和被其包裹的Toolbar同時設置了app:title=" "屬性時,CollapsingToolbarLayout的生效;若CollapsingToolbarLayout沒有設置而Toolbar設置了,Toolbar的生效;都沒有設置將沒有title.

c)設置title大小、顏色等樣式

(此處指的是完全擴張時)
app:expandedTitleTextAppearance=" "  設置大小、顏色等樣式

也可以通過代碼來設置:
setExpandedTitleColor( )  設置顏色
setExpandedTitleTextAppearance( )  設置大小、顏色等樣式
(此處指的是折疊到最小時)
app:collapsedTitleTextAppearance=""  設置大小、顏色等樣式

setCollapsedTitleTextColor()  設置顏色
setCollapsedTitleTextAppearance()  設置大小、顏色等樣式

d)設置title位置

(此處指的是折疊到最小時)
屬性:
app:collapsedTitleGravity=" "

代碼:
setCollapsedTitleGravity()
(此處指的是完全擴張時)
屬性:
app:expandedTitleGravity=" "

代碼:
setExpandedTitleGravity()

e)設置CollapsingToolbarLayout完全擴張時的Margin

app:expandedTitleMargin=""
app:expandedTitleMarginTop=""
app:expandedTitleMarginBottom=""
app:expandedTitleMarginStart=""
app:expandedTitleMarginEnd=""

(2)Content scrim(內容紗布):當CollapsingToolbarLayout折疊到一定閾值的時候,為其蓋上一層"紗布".

通過 app:contentScrim=" "屬性或者setContentScrim(Drawable)方法來設置該“紗布”

Tips:紗布可以是一種顏色,也可以是一張圖片

(3)Status bar scrim(狀態欄紗布):根據滾動位置是否到達一個閥值決定是否對狀態欄蓋上一層“紗布”,你可以通過app:statusBarScrim=""屬性或者setStatusBarScrim(Drawable)方法來設置該“紗布”.
僅僅在LOLLIPOP設備上面(Android 5.0---API21)起作用.

(4)Parallax scrolling children(有視差地滾動子View):其實就是在視覺上比CollapsingToolbarLayout中其它子View滾動的慢一點

app:layout_collapseMode="parallax " 用在被CollapsingToolbarLayout包裹的子View上
然后用:
app:layout_collapseParallaxMultiplier=" "控制視差系數
或者 通過setParallaxMultiplier(float)控制視差系數

(5)Pinned position children(固定子View位置 ):子View可以選擇是否在全局空間上固定位置,這對于Toolbar來說非常有用,因為當布局在移動時,可以將Toolbar固定位置而不受移動的影響

在被CollapsingToolbarLayout包裹的子View上設置:
    app:layout_collapseMode="pin" 

4、代碼

<?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.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/text" />
    </android.support.v4.widget.NestedScrollView>

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

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

            app:title="一生所愛"
            app:collapsedTitleGravity="center"
            app:collapsedTitleTextAppearance="@style/MyCollapsedTitleStyle"
            app:expandedTitleGravity="right|bottom"
            app:expandedTitleTextAppearance="@style/MyExpandedTitleStyle"
            app:contentScrim="@android:color/holo_blue_dark" >

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="233dp"
                android:scaleType="centerCrop"
                android:src="@mipmap/zy"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.7">
            </ImageView>

            <android.support.v7.widget.Toolbar
                android:layout_width="match_parent"
                android:layout_height="?android:attr/actionBarSize"
                app:layout_collapseMode="pin" />
        </android.support.design.widget.CollapsingToolbarLayout>

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

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

styles.xml中:

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>

        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

    <style name="MyExpandedTitleStyle" parent="TextAppearance.Design.CollapsingToolbar.Expanded">
        <item name="android:textSize">25sp</item>
        <item name="android:textColor">@android:color/holo_purple</item>
    </style>

    <style name="MyCollapsedTitleStyle">
        <item name="android:textSize">16sp</item>
        <item name="android:textColor">@android:color/white</item>
    </style>
</resources>

三、小結

使用AppBarLayout、CollapsingToolbarLayout可以實現很多酷炫的效果,你還在等什么,還不去嘗試一下!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,527評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,687評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,640評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,957評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,682評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,011評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,009評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,183評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,714評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,435評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,665評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,148評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,838評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,251評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,588評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,379評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,627評論 2 380

推薦閱讀更多精彩內容