CoordinatorLayout與滾動(dòng)的處理

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0717/3196.html

概覽

CoordinatorLayout實(shí)現(xiàn)了多種Material Design中提到的滾動(dòng)效果。目前這個(gè)框架提供了幾種不用寫動(dòng)畫代碼就能工作的方法勉盅,這些效果包括:

讓浮動(dòng)操作按鈕上下滑動(dòng)含鳞,為Snackbar留出空間绒北。

擴(kuò)展或者縮小Toolbar或者頭部厨幻,讓主內(nèi)容區(qū)域有更多的空間找田。

控制哪個(gè)view應(yīng)該擴(kuò)展還是收縮毒姨,以及其顯示大小比例冤竹,包括視差滾動(dòng)效果動(dòng)畫宿礁。

設(shè)置

首先確保遵循了Design Support Library的使用說明案铺。

浮動(dòng)操作按鈕與Snackbar

CoordinatorLayout可以用來配合浮動(dòng)操作按鈕的?layout_anchor?和?layout_gravity屬性創(chuàng)造出浮動(dòng)效果,詳情請(qǐng)參見浮動(dòng)操作按鈕指南梆靖。

當(dāng)Snackbar在顯示的時(shí)候控汉,往往出現(xiàn)在屏幕的底部。為了給Snackbar留出空間返吻,浮動(dòng)操作按鈕需要向上移動(dòng)姑子。

只要使用CoordinatorLayout作為基本布局,將自動(dòng)產(chǎn)生向上移動(dòng)的動(dòng)畫测僵。浮動(dòng)操作按鈕有一個(gè)默認(rèn)的 behavior來檢測(cè)Snackbar的添加并讓按鈕在Snackbar之上呈現(xiàn)上移與Snackbar等高的動(dòng)畫街佑。

android:id="@+id/main_content"

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:id="@+id/rvToDoList"

android:layout_width="match_parent"

android:layout_height="match_parent">

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="bottom|right"

android:layout_margin="16dp"

android:src="@mipmap/ic_launcher"

app:layout_anchor="@id/rvToDoList"

app:layout_anchorGravity="bottom|right|end"/>

Toolbar的擴(kuò)展與收縮

首先需要確保你不是使用已經(jīng)過時(shí)的ActionBar。務(wù)必遵循使用ToolBar作為actionbar這篇文章的指南捍靠。同樣沐旨,這里也需要CoordinatorLayout作為主布局容器。

xmlns:app="http://schemas.android.com/apk/res-auto"

android:id="@+id/main_content"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:fitsSystemWindows="true">

android:id="@+id/toolbar"

android:layout_width="match_parent"

android:layout_height="?attr/actionBarSize"

app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

響應(yīng)滾動(dòng)事件

接下來榨婆,我們必須使用一個(gè)容器布局:AppBarLayout來讓Toolbar響應(yīng)滾動(dòng)事件磁携。

android:id="@+id/appbar"

android:layout_width="match_parent"

android:layout_height="@dimen/detail_backdrop_height"

android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"

android:fitsSystemWindows="true">

android:id="@+id/toolbar"

android:layout_width="match_parent"

android:layout_height="?attr/actionBarSize"

app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

注意:根據(jù)官方的谷歌文檔,AppBarLayout目前必須是第一個(gè)嵌套在CoordinatorLayout里面的子view(現(xiàn)在貌似不是這樣子良风,正確的理解是:AppBarLayout必須是CoordinatorLayout的直接子View)谊迄。

然后,我們需要定義AppBarLayout與滾動(dòng)視圖之間的聯(lián)系拖吼。在RecyclerView或者任意支持嵌套滾動(dòng)的view比如NestedScrollView上添加app:layout_behavior鳞上。support library包含了一個(gè)特殊的字符串資源@string/appbar_scrolling_view_behavior,它和AppBarLayout.ScrollingViewBehavior相匹配吊档,用來通知AppBarLayout 這個(gè)特殊的view何時(shí)發(fā)生了滾動(dòng)事件篙议,這個(gè)behavior需要設(shè)置在觸發(fā)事件(滾動(dòng))的view之上。

android:id="@+id/rvToDoList"

android:layout_width="match_parent"

android:layout_height="match_parent"

app:layout_behavior="@string/appbar_scrolling_view_behavior">

當(dāng)CoordinatorLayout發(fā)現(xiàn)RecyclerView中定義了這個(gè)屬性,它會(huì)搜索自己所包含的其他view鬼贱,看看是否有view與這個(gè)behavior相關(guān)聯(lián)移怯。AppBarLayout.ScrollingViewBehavior描述了RecyclerView與AppBarLayout之間的依賴關(guān)系。RecyclerView的任意滾動(dòng)事件都將觸發(fā)AppBarLayout或者AppBarLayout里面view的改變这难。

AppBarLayout里面定義的view只要設(shè)置了app:layout_scrollFlags屬性舟误,就可以在RecyclerView滾動(dòng)事件發(fā)生的時(shí)候被觸發(fā):

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:fitsSystemWindows="true"

android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

android:id="@+id/toolbar"

android:layout_width="match_parent"

android:layout_height="?attr/actionBarSize"

app:layout_scrollFlags="scroll|enterAlways"/>

app:layout_scrollFlags屬性里面必須至少啟用scroll這個(gè)flag,這樣這個(gè)view才會(huì)滾動(dòng)出屏幕姻乓,否則它將一直固定在頂部嵌溢。可以使用的其他flag有:

enterAlways: 一旦向下滾動(dòng)這個(gè)view就可見蹋岩。

enterAlwaysCollapsed:顧名思義赖草,這個(gè)flag定義的是何時(shí)進(jìn)入(已經(jīng)消失之后何時(shí)再次顯示)。假設(shè)你定義了一個(gè)最小高度(minHeight)同時(shí)enterAlways也定義了剪个,那么view將在到達(dá)這個(gè)最小高度的時(shí)候開始顯示秧骑,并且從這個(gè)時(shí)候開始慢慢展開,當(dāng)滾動(dòng)到頂部的時(shí)候展開完扣囊。

exitUntilCollapsed: 同樣顧名思義乎折,這個(gè)flag時(shí)定義何時(shí)退出,當(dāng)你定義了一個(gè)minHeight侵歇,這個(gè)view將在滾動(dòng)到達(dá)這個(gè)最小高度的時(shí)候消失骂澄。

記住,要把帶有scroll flag的view放在前面盒至,這樣收回的view才能讓正常退出酗洒,而固定的view繼續(xù)留在頂部。

此時(shí)枷遂,你應(yīng)該注意到我們的Toolbar能夠響應(yīng)滾動(dòng)事件了樱衷。

制造折疊效果

如果想制造toolbar的折疊效果,我們必須把Toolbar放在CollapsingToolbarLayout中:

android:id="@+id/collapsing_toolbar"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:fitsSystemWindows="true"

app:contentScrim="?attr/colorPrimary"

app:expandedTitleMarginEnd="64dp"

app:expandedTitleMarginStart="48dp"

app:layout_scrollFlags="scroll|exitUntilCollapsed">

android:id="@+id/toolbar"

android:layout_width="match_parent"

android:layout_height="?attr/actionBarSize"

app:layout_scrollFlags="scroll|enterAlways">

現(xiàn)在效果就成了:

通常酒唉,我們我們都是設(shè)置Toolbar的title矩桂,而現(xiàn)在,我們需要把title設(shè)置在CollapsingToolBarLayout上痪伦,而不是Toolbar侄榴。

CollapsingToolbarLayoutcollapsingToolbar=

(CollapsingToolbarLayout)findViewById(R.id.collapsing_toolbar);

collapsingToolbar.setTitle("Title");

制造視差效果

CollapsingToolbarLayout還能讓我們做出更高級(jí)的動(dòng)畫,比如在里面放一個(gè)ImageView网沾,然后在它折疊的時(shí)候漸漸淡出癞蚕。同時(shí)在用戶滾動(dòng)的時(shí)候title的高度也會(huì)隨著改變。

為了制造出這種效果辉哥,我們添加一個(gè)定義了app:layout_collapseMode="parallax"?屬性的ImageView桦山。

android:id="@+id/collapsing_toolbar"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:fitsSystemWindows="true"

app:contentScrim="?attr/colorPrimary"

app:expandedTitleMarginEnd="64dp"

app:expandedTitleMarginStart="48dp"

app:layout_scrollFlags="scroll|exitUntilCollapsed">

android:id="@+id/toolbar"

android:layout_width="match_parent"

android:layout_height="?attr/actionBarSize"

app:layout_scrollFlags="scroll|enterAlways">

android:src="@drawable/cheese_1"

app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:scaleType="centerCrop"

app:layout_collapseMode="parallax"

android:minHeight="100dp"/>

自定義Behavior

CoordinatorLayout 與浮動(dòng)操作按鈕中我們討論了一個(gè)自定義behavior的例子攒射。注: 譯文http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0718/3197.html

CoordinatorLayout的工作原理是搜索定義了CoordinatorLayout Behavior的子view恒水,不管是通過在xml中使用app:layout_behavior標(biāo)簽還是通過在代碼中對(duì)view類使用@DefaultBehavior修飾符來添加注解会放。當(dāng)滾動(dòng)發(fā)生的時(shí)候,CoordinatorLayout會(huì)嘗試觸發(fā)那些聲明了依賴的子view钉凌。

要自己定義CoordinatorLayout?Behavior咧最,你需要實(shí)現(xiàn)layoutDependsOn() 和onDependentViewChanged()兩個(gè)方法。比如AppBarLayout.Behavior 就定義了這兩個(gè)關(guān)鍵方法御雕。這個(gè)behavior用于當(dāng)滾動(dòng)發(fā)生的時(shí)候讓AppBarLayout發(fā)生改變矢沿。

publicbooleanlayoutDependsOn(CoordinatorLayoutparent,Viewchild,Viewdependency){

returndependencyinstanceofAppBarLayout;

}

publicbooleanonDependentViewChanged(CoordinatorLayoutparent,Viewchild,Viewdependency){

//?check?the?behavior?triggered

android.support.design.widget.CoordinatorLayout.Behaviorbehavior=((android.support.design.widget.CoordinatorLayout.LayoutParams)dependency.getLayoutParams()).getBehavior();

if(behaviorinstanceofAppBarLayout.Behavior){

//?do?stuff?here

}

}

理解如何實(shí)現(xiàn)這些自定義behavior的最好途徑是研究AppBarLayout.Behavior 和?FloatingActionButtion.Behavior。雖然這些源代碼還沒有放出來饮笛,但是你可以使用Android Studio 1.2集成的反編譯器來查看咨察。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市福青,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌脓诡,老刑警劉巖无午,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異祝谚,居然都是意外死亡宪迟,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門交惯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來次泽,“玉大人,你說我怎么就攤上這事席爽∫饣纾” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵只锻,是天一觀的道長玖像。 經(jīng)常有香客問我,道長齐饮,這世上最難降的妖魔是什么捐寥? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮祖驱,結(jié)果婚禮上握恳,老公的妹妹穿的比我還像新娘。我一直安慰自己捺僻,他們只是感情好乡洼,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般就珠。 火紅的嫁衣襯著肌膚如雪寇壳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天妻怎,我揣著相機(jī)與錄音壳炎,去河邊找鬼。 笑死逼侦,一個(gè)胖子當(dāng)著我的面吹牛匿辩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播榛丢,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼铲球,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了晰赞?” 一聲冷哼從身側(cè)響起稼病,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎掖鱼,沒想到半個(gè)月后然走,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡戏挡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年芍瑞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片褐墅。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡拆檬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出妥凳,到底是詐尸還是另有隱情竟贯,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布猾封,位于F島的核電站澄耍,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏晌缘。R本人自食惡果不足惜齐莲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望磷箕。 院中可真熱鬧选酗,春花似錦、人聲如沸岳枷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至殿衰,卻和暖如春朱庆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背闷祥。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國打工娱颊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人凯砍。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓箱硕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親悟衩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子剧罩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • CoordinatorLayout與滾動(dòng)的處理泡在網(wǎng)上的日子 發(fā)表于 2015-07-17 17:10 第 308...
    六指禪閱讀 725評(píng)論 0 0
  • 轉(zhuǎn)載自:http://www.open-open.com/lib/view/open1437312265428.h...
    HEXG_閱讀 1,648評(píng)論 0 1
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,519評(píng)論 25 707
  • 讀《三個(gè)行動(dòng)指導(dǎo),提高你的成功率》讀后感 現(xiàn)今社會(huì)是高速發(fā)展的社會(huì)座泳,高速發(fā)展往往意味著做事需要提高效率惠昔,可...
    書中黃金屋顏如玉閱讀 108評(píng)論 0 0
  • 文/塵間紅葉 1 哥家的兒子叫勝天,去年中考挑势。他就讀于區(qū)實(shí)驗(yàn)中學(xué)舰罚,三年來一直穩(wěn)居班內(nèi)前三,是很多人嘴里“別人家的孩...
    塵間紅葉閱讀 436評(píng)論 27 10