一、寫在前面
其實(shí)博主在之前已經(jīng)對(duì) Design 包的各個(gè)控件都做了博文說(shuō)明,無(wú)奈個(gè)人覺得理解不夠深入隅居,所以有了這篇更加深入的介紹钠至,希望各位看官拍磚~
二、從是什么開始
1胎源、首先我們得知道 CoordinatorLayout
是什么玩意兒棉钧,到底有什么用,我們不妨看看官方文檔的描述:
CoordinatorLayout
是一個(gè) “加強(qiáng)版”FrameLayout
涕蚤, 它主要有兩個(gè)用途:
- 用作應(yīng)用的頂層布局管理器宪卿,也就是作為用戶界面中所有 UI 控件的容器;
- 用作相互之間具有特定交互行為的 UI 控件的容器,通過(guò)為
CoordinatorLayout
的子 View 指定 Behavior万栅, 就可以實(shí)現(xiàn)它們之間的交互行為佑钾。 Behavior 可以用來(lái)實(shí)現(xiàn)一系列的交互行為和布局變化,比如說(shuō)側(cè)滑菜單烦粒、可滑動(dòng)刪除的 UI 元素休溶,以及跟隨著其他 UI 控件移動(dòng)的按鈕等。
其實(shí)總結(jié)出來(lái)就是 CoordinatorLayout
是一個(gè)布局管理器撒遣,相當(dāng)于一個(gè)增強(qiáng)版的 FrameLayout
邮偎,但是它神奇在于可以實(shí)現(xiàn)它的子 View 之間的交互行為。
2义黎、交互行為禾进?
先看個(gè)簡(jiǎn)單的效果圖
可能大家看到這,就自然能想到觀察者模式廉涕,或者我前面寫的Rx模式:這可能是最好的RxJava 2.x 教程(完結(jié)版)
我們的 Button
就是一個(gè)被觀察者泻云,TextView 作為一個(gè)觀察者,當(dāng) Button
移動(dòng)的時(shí)候通知 TextView
狐蜕, TextView
就跟著移動(dòng)宠纯。看看其布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.nanchen.coordinatorlayoutdemo.CoordinatorActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="觀察者"
app:layout_behavior=".FollowBehavior"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="被觀察者"
android:layout_gravity="center"
android:id="@+id/btn"/>
</android.support.design.widget.CoordinatorLayout>
很簡(jiǎn)單层释,一個(gè) TextView
婆瓜, 一個(gè) Button
, 外層用 CoordinatorLayout
贡羔, 然后給我們的 TextView
加一個(gè)自定義的 Behavior
文件廉白,內(nèi)容如下:
package com.nanchen.coordinatorlayoutdemo;
import android.content.Context;
import android.support.design.widget.CoordinatorLayout;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
/**
*
* 自定義 CoordinatorLayout 的 Behavior, 泛型為觀察者 View ( 要跟著別人動(dòng)的那個(gè) )
*
* 必須重寫兩個(gè)方法乖寒,layoutDependOn和onDependentViewChanged
*
* @author nanchen
* @fileName CoordinatorLayoutDemo
* @packageName com.nanchen.coordinatorlayoutdemo
* @date 2016/12/13 10:13
*/
public class FollowBehavior extends CoordinatorLayout.Behavior<TextView>{
/**
* 構(gòu)造方法
*/
public FollowBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* 判斷child的布局是否依賴 dependency
*
* 根據(jù)邏輯來(lái)判斷返回值猴蹂,返回 false 表示不依賴,返回 true 表示依賴
*
* 在一個(gè)交互行為中楣嘁,Dependent View 的變化決定了另一個(gè)相關(guān) View 的行為磅轻。
* 在這個(gè)例子中珍逸, Button 就是 Dependent View,因?yàn)?TextView 跟隨著它聋溜。
* 實(shí)際上 Dependent View 就相當(dāng)于我們前面介紹的被觀察者
*
*/
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, TextView child, View dependency) {
return dependency instanceof Button;
}
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, TextView child, View dependency) {
child.setX(dependency.getX());
child.setY(dependency.getY() + 100);
return true;
}
}
重點(diǎn)看看其中重寫的兩個(gè)方法 layoutDependsOn()
和 onDependentViewChanged()
谆膳。在介紹這兩個(gè)方法的作用前,我們先來(lái)介紹一下 Dependent View勤婚。在一個(gè)交互行為中摹量,Dependent View 的變化決定了另一個(gè)相關(guān) View 的行為。在這個(gè)例子中馒胆, Button 就是 Dependent View缨称, 因?yàn)?TextView 跟隨著它。實(shí)際上 Dependent View 就相當(dāng)于我們前面介紹的被觀察者祝迂。
知道了這個(gè)概念睦尽,讓我們看看重寫的兩個(gè)方法的作用:
layoutDependsOn()
:這個(gè)方法在對(duì)界面進(jìn)行布局時(shí)至少會(huì)調(diào)用一次,用來(lái)確定本次交互行為中的 Dependent View型雳,在上面的代碼中当凡,當(dāng)Dependency
是Button 類的實(shí)例時(shí)返回 true,就可以讓系統(tǒng)知道布局文件中的 Button 就是本次交互行為中的 Dependent View纠俭。onDependentViewChanged()
:當(dāng) Dependent View 發(fā)生變化時(shí)沿量,這個(gè)方法會(huì)被調(diào)用,參數(shù)中的child相當(dāng)于本次交互行為中的觀察者冤荆,觀察者可以在這個(gè)方法中對(duì)被觀察者的變化做出響應(yīng)朴则,從而完成一次交互行為。
所以我們現(xiàn)在可以開始寫Activity中的代碼:
findViewById(R.id.btn).setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_MOVE){
view.setX(motionEvent.getRawX()-view.getWidth()/2);
view.setY(motionEvent.getRawY()-view.getHeight()/2);
}
return true;
}
});
這樣一來(lái)钓简,我們就完成了為 TextView 和Button 設(shè)置跟隨移動(dòng)這個(gè)交互行為乌妒。很簡(jiǎn)單有木有,其實(shí)為 CoordinatorLayout
的子 View 設(shè)置交互行為只需三步:
自定義一個(gè)繼承自 Behavior
類的交互行為類外邓;
把觀察者的 layout_behavior
屬性設(shè)置為自定義行為類的類名撤蚊;
重寫 Behavior
類的相關(guān)方法來(lái)實(shí)現(xiàn)我們想要的交互行為。
值得注意的是损话,有些時(shí)候侦啸,并不需要我們自己來(lái)定義一個(gè) Behavior
類,因?yàn)橄到y(tǒng)為我們預(yù)定義了不少 Behavior
類丧枪。在接下來(lái)的篇章中光涂,我們會(huì)做出進(jìn)一步的介紹。
3豪诲、更進(jìn)一步
現(xiàn)在我們已經(jīng)知道了怎么通過(guò)給 CoordinatorLayout
的子 View 設(shè)置 Behavior
來(lái)實(shí)現(xiàn)交互行為《ソ荩現(xiàn)在挂绰,讓我們更進(jìn)一步地挖掘下 CoordinatorLayout
屎篱, 深入了解一下隱藏在表象背后的神秘細(xì)節(jié)服赎。
實(shí)際上, CoordinatorLayout
本身并沒有做過(guò)多工作交播,實(shí)現(xiàn)交互行為的主要幕后推手是 CoordinatorLayout
的內(nèi)部類—— Behavior
重虑。通過(guò)為 CoordinatorLayout
的**直接子 View **綁定一個(gè) Behavior
,這個(gè) Behavior
就會(huì)攔截發(fā)生在這個(gè) View 上的 Touch 事件秦士、嵌套滾動(dòng)等缺厉。不僅如此,Behavior
還能攔截對(duì)與它綁定的 View 的測(cè)量及布局隧土。關(guān)于嵌套滾動(dòng)提针,我們會(huì)在后續(xù)文章中進(jìn)行詳細(xì)介紹。下面我們來(lái)深入了解一下 Behavior
是如何做到這一切的曹傀。
4辐脖、深入理解 Behavior
- 攔截 Touch 事件
當(dāng)我們?yōu)橐粋€(gè) CoordinatorLayout
的直接子 View 設(shè)置了 Behavior 時(shí),這個(gè) Behavior 就能攔截發(fā)生在這個(gè) View 上的 Touch 事件皆愉,那么它是如何做到的呢嗜价?實(shí)際上, CoordinatorLayout
重寫了 onInterceptTouchEvent()
方法幕庐,并在其中給 Behavior 開了個(gè)后門久锥,讓它能夠先于 View 本身處理 Touch 事件。具體來(lái)說(shuō)异剥, CoordinatorLayout
的 onInterceptTouchEvent()
方法中會(huì)遍歷所有直接子 View 瑟由,對(duì)于綁定了 Behavior 的直接子 View 調(diào)用 Behavior 的 onInterceptTouchEvent() 方法,若這個(gè)方法返回 true届吁, 那么后續(xù)本該由相應(yīng)子 View 處理的 Touch 事件都會(huì)交由 Behavior 處理错妖,而 View 本身表示懵逼,完全不知道發(fā)生了什么疚沐。
- 攔截測(cè)量及布局
了解了 Behavior 是怎養(yǎng)攔截 Touch 事件的暂氯,想必大家已經(jīng)猜出來(lái)了它攔截測(cè)量及布局事件的方式 —— CoordinatorLayout 重寫了測(cè)量及布局相關(guān)的方法并為 Behavior 開了個(gè)后門。沒錯(cuò)亮蛔,真相就是如此痴施。
CoordinatorLayout 在 onMeasure()
方法中,會(huì)遍歷所有直接子 View 究流,若該子 View 綁定了一個(gè) Behavior 辣吃,就會(huì)調(diào)用相應(yīng) Behavior 的 onMeasureChild()
方法,若此方法返回 true芬探,那么 CoordinatorLayout 對(duì)該子 View 的測(cè)量就不會(huì)進(jìn)行神得。這樣一來(lái), Behavior 就成功接管了對(duì) View 的測(cè)量偷仿。
同樣哩簿,CoordinatorLayout 在 onLayout()
方法中也做了與 onMeasure()
方法中相似的事宵蕉,讓 Behavior 能夠接管對(duì)相關(guān)子 View 的布局。
- View 的依賴關(guān)系的確定
現(xiàn)在节榜,我們?cè)谔骄恳幌陆换バ袨橹械膬蓚€(gè) View 之間的依賴關(guān)系是怎么確定的羡玛。我們稱 child 為交互行為中根據(jù)另一個(gè) View 的變化做出響應(yīng)的那個(gè)個(gè)體,而 Dependent View 為child所依賴的 View宗苍。實(shí)際上稼稿,確立 child 和 Dependent View 的依賴關(guān)系有兩種方式:
顯式依賴:為 child 綁定一個(gè) Behavior,并在 Behavior 類的
layoutDependsOn()
方法中做手腳讳窟。即當(dāng)傳入的dependency
為 Dependent View 時(shí)返回 true让歼,這樣就建立了 child 和 Dependent View 之間的依賴關(guān)系。隱式依賴:通過(guò)我們最開始提到的錨(anchor)來(lái)確立丽啡。具體做法可以這樣:在 XML 布局文件中是越,把 child 的
layout_anchor
屬性設(shè)為 Dependent View 的id,然后 child 的layout_anchorGravity
屬性用來(lái)描述為它想對(duì) Dependent View 的變化做出什么樣的響應(yīng)碌上。關(guān)于這個(gè)我們會(huì)在后續(xù)篇章給出具體示例倚评。
無(wú)論是隱式依賴還是顯式依賴,在 Dependent View 發(fā)生變化時(shí)馏予,相應(yīng) Behavior 類的 onDependentViewChanged()
方法都會(huì)被調(diào)用天梧,在這個(gè)方法中,我們可以讓 child 做出改變以響應(yīng) Dependent View 的變化霞丧。
三呢岗、玩轉(zhuǎn)AppBarLayout
實(shí)際上我們?cè)趹?yīng)用中有 CoordinatorLayout 的地方通常都會(huì)有 AppBarLayout 的聯(lián)用,作為同樣的出自 Design 包的庫(kù)蛹尝,我們看看官方文檔怎么說(shuō):
AppBarLayout 是一個(gè)垂直的 LinearLayout后豫,實(shí)現(xiàn)了 Material Design 中 App bar 的 Scrolling Gestures 特性。AppBarLayout 的子 View 應(yīng)該聲明想要具有的“滾動(dòng)行為”突那,這可以通過(guò) layout_scrollFlags 屬性或是 setScrollFlags() 方法來(lái)指定挫酿。
AppBarLayout 只有作為 CoordinatorLayout 的直接子 View 時(shí)才能正常工作,為了讓 AppBarLayout 能夠知道何時(shí)滾動(dòng)其子 View愕难,我們還應(yīng)該在 CoordinatorLayout 布局中提供一個(gè)可滾動(dòng) View早龟,我們稱之為 Scrolling View。
Scrolling View 和 AppBarLayout 之間的關(guān)聯(lián)猫缭,通過(guò)將 Scrolling View 的 Behavior 設(shè)為 AppBarLayout.ScrollingViewBehavior 來(lái)建立葱弟。
1、一般怎么用猜丹?
AppBar
是 Design 的一個(gè)概念芝加,其實(shí)我們也可以把它看做一種 5.0 出的 ToolBar
,先感受一下 AppBarLayout
+ CoordinatorLayout
的魅力射窒。
實(shí)際效果就是這樣藏杖,當(dāng)向上滑動(dòng) View 的時(shí)候老赤,ToolBar 會(huì)小時(shí),向下滑動(dòng)的時(shí)候制市,ToolBar 又會(huì)出現(xiàn),但別忘了弊予,這是 AppBarLayout 的功能祥楣,ToolBar 可辦不到。由于要滑動(dòng)汉柒,那么我們的 AppBarLayout 一定是和可以滑動(dòng)的 View 一起使用的误褪,比如
RecyclerView
,ScollView
等碾褂。我們看看上面的到底怎么實(shí)現(xiàn)的:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_coor_app_bar"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.nanchen.coordinatorlayoutdemo.CoorAppBarActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recycler"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
我們可以看到兽间,上面出現(xiàn)了一個(gè) app:layouy_scrollFrags
的自定義屬性設(shè)置,這個(gè)屬性可以定義我們不同的滾動(dòng)行為正塌。
**2嘀略、layout_scrollFlags **
根據(jù)官方文檔,layout_scrollFlags
的取值可以為以下幾種乓诽。
scroll
設(shè)成這個(gè)值的效果就好比本 View 和 Scrolling view 是“一體”的帜羊。具體示例我們?cè)谏厦嬉呀?jīng)給出。有一點(diǎn)特別需要我們的注意鸠天,為了其他的滾動(dòng)行為生效讼育,必須同時(shí)指定 Scroll 和相應(yīng)的標(biāo)記,比如我們想要exitUntilCollapsed
所表現(xiàn)的滾動(dòng)行為稠集,必須將 layout_scrollFlags 指定為scroll|exitUntilCollapsed
奶段。exitUntilCollapsed
當(dāng)本 View 離開屏幕時(shí),會(huì)被“折疊”直到達(dá)到其最小高度剥纷。我們可以這樣理解這個(gè)效果:當(dāng)我們開始向上滾動(dòng) Scrolling view 時(shí)痹籍,本 View 會(huì)先接管滾動(dòng)事件,這樣本 View 會(huì)先進(jìn)行滾動(dòng)晦鞋,直到滾動(dòng)到了最小高度(折疊了)词裤,Scrolling view 才開始實(shí)際滾動(dòng)。而當(dāng)本 View 已完全折疊后鳖宾,再向下滾動(dòng) Scrolling view吼砂,直到 Scrolling view 頂部的內(nèi)容完全顯示后,本 View 才會(huì)開始向下滾動(dòng)以顯現(xiàn)出來(lái)鼎文。enterAlways
當(dāng) Scrolling view 向下滾動(dòng)時(shí)渔肩,本 View 會(huì)一起跟著向下滾動(dòng)。實(shí)際上就好比我們同時(shí)對(duì) Scrolling view 和本 View 進(jìn)行向下滾動(dòng)拇惋。enterAlwaysCollapsed
從名字上就可以看出周偎,這是在enterAlways
的基礎(chǔ)上抹剩,加上了“折疊”的效果。當(dāng)我們開始向下滾動(dòng) Scrolling View 時(shí)蓉坎,本 View 會(huì)一起跟著滾動(dòng)直到達(dá)到其“折疊高度”(即最小高度)澳眷。然后當(dāng) Scrolling View 滾動(dòng)至頂部?jī)?nèi)容完全顯示后,再向下滾動(dòng) Scrolling View蛉艾,本 View 會(huì)繼續(xù)滾動(dòng)到完全顯示出來(lái)钳踊。snap
在一次滾動(dòng)結(jié)束時(shí),本 View 很可能只處于“部分顯示”的狀態(tài)勿侯,加上這個(gè)標(biāo)記能夠達(dá)到“要么完全隱藏拓瞪,要么完全顯示”的效果。
四助琐、CollapsingToolBarLayout
這個(gè)東西祭埂,我相信很多博客和技術(shù)文章都會(huì)把 CollapsingToolBarLayout
和 CoordinatorLayout
放一起講,這個(gè)東西的確很牛兵钮。我們同樣先看看官方文檔介紹:
CollapsingToolbarLayout 通常用來(lái)在布局中包裹一個(gè) Toolbar蛆橡,以實(shí)現(xiàn)具有“折疊效果“”的頂部欄。它需要是 AppBarLayout 的直接子 View掘譬,這樣才能發(fā)揮出效果航罗。
CollapsingToolbarLayout包含以下特性:
- Collasping title(可折疊標(biāo)題):當(dāng)布局完全可見時(shí),這個(gè)標(biāo)題比較大屁药;當(dāng)折疊起來(lái)時(shí)粥血,標(biāo)題也會(huì)變小。標(biāo)題的外觀可以通過(guò) expandedTextAppearance 和 collapsedTextAppearance 屬性來(lái)調(diào)整酿箭。
- Content scrim(內(nèi)容紗布):根據(jù) CollapsingToolbarLayout 是否滾動(dòng)到一個(gè)臨界點(diǎn)复亏,內(nèi)容紗布會(huì)顯示或隱藏$缘眨可以通過(guò) setContentScrim(Drawable) 來(lái)設(shè)置內(nèi)容紗布缔御。
- Status bar scrim(狀態(tài)欄紗布):也是根據(jù)是否滾動(dòng)到臨界點(diǎn),來(lái)決定是否顯示妇蛀「唬可以通過(guò) setStatusBarScrim(Drawable) 方法來(lái)設(shè)置。這個(gè)特性只有在 Android 5.0 及其以上版本评架,我們?cè)O(shè)置 fitSystemWindows 為 ture 時(shí)才能生效眷茁。
- Parallax scrolling children(視差滾動(dòng)子 View):子 View 可以選擇以“視差”的方式來(lái)進(jìn)行滾動(dòng)。(視覺效果上就是子 View 滾動(dòng)的比其他 View 稍微慢些)
- Pinned position children:子 View 可以選擇固定在某一位置上纵诞。
上面的描述有些抽象上祈,實(shí)際上對(duì)于 Content scrim
、Status bar scrim
我們可以暫時(shí)予以忽略,只要留個(gè)大概印象待以后需要時(shí)再查閱相關(guān)資料即可登刺。下面我們通過(guò)一個(gè)常見的例子介紹下 CollapsingToolbarLayout
的基本使用姿勢(shì)籽腕。
我們來(lái)看看一個(gè)常用的效果:
看看布局:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_coor_tool_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.nanchen.coordinatorlayoutdemo.CoorToolBarActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:theme="@style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="200dp"
app:contentScrim="@color/colorPrimary"
app:expandedTitleMarginStart="100dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
app:statusBarScrim="@android:color/transparent"
app:titleEnabled="false">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
android:src="@mipmap/logo"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.6"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:title=""/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recycler"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
<TextView
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_marginLeft="16dp"
android:layout_marginTop="-100dp"
android:alpha="0"
android:elevation="10dp"
android:gravity="center_vertical"
android:text="愛吖校推-你關(guān)注的,我們才推"
android:textColor="@android:color/white"
android:textSize="20sp"
android:textStyle="bold"
app:layout_behavior=".SimpleViewBehavior"
app:svb_dependOn="@id/appbar"
app:svb_dependType="y"
app:svb_targetAlpha="1"
app:svb_targetY="0dp"/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:src="@mipmap/ic_start"
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right"/>
</android.support.design.widget.CoordinatorLayout>
我們?cè)?XML 文件中為 CollapsingToolBarLayout 的 layout_scrollFlags 指定為 scroll|exitUntilCollapsed|snap
纸俭,這樣便實(shí)現(xiàn)了向上滾動(dòng)的折疊效果皇耗。
CollapsingToolbarLayout
本質(zhì)上同樣是一個(gè) FrameLayout
,我們?cè)诓季治募兄付艘粋€(gè) ImageView
和一個(gè) Toolbar
揍很。ImageView
的layout_collapseMode
屬性設(shè)為了 parallax
郎楼,也就是我們前面介紹的視差滾動(dòng);而 Toolbar 的 layout_collaspeMode
設(shè)為了 pin
女轿,也就是 Toolbar 會(huì)始終固定在頂部。
五壕翩、寫在最后
本次的 Design 包下的 CoordinatorLayout
和 AppBarLayout
就講述到這里蛉迹,后續(xù)還將持續(xù)更新,歡迎拍磚~
查看源碼請(qǐng)移步 Github:https://github.com/nanchen2251/CoordinatorAppBarDemo