CoordinatorLayout與滾動的處理

CoordinatorLayout與滾動的處理
泡在網(wǎng)上的日子 發(fā)表于 2015-07-17 17:10 第 30892 次閱讀 CoordinatorLayout
5
編輯推薦:稀土掘金乎婿,這是一個針對技術(shù)開發(fā)者的一個應(yīng)用测僵,你可以在掘金上獲取最新最優(yōu)質(zhì)的技術(shù)干貨,不僅僅是Android知識谢翎、前端捍靠、后端以至于產(chǎn)品和設(shè)計都有涉獵沐旨,想成為全棧工程師的朋友不要錯過!

英文原文:https://guides.codepath.com/android/Handling-Scrolls-with-CoordinatorLayout

這篇文章專門講解和CoordinatorLayout相關(guān)的知識點剂公,這也是Design Support Library中最重要與最難的部分希俩。

概覽
CoordinatorLayout 實現(xiàn)了多種Material Design中提到的滾動效果。目前這個框架提供了幾種不用寫動畫代碼就能工作的方法纲辽,這些效果包括:

讓浮動操作按鈕上下滑動,為Snackbar留出空間璃搜。

擴展或者縮小Toolbar或者頭部拖吼,讓主內(nèi)容區(qū)域有更多的空間。

控制哪個view應(yīng)該擴展還是收縮这吻,以及其顯示大小比例吊档,包括視差滾動效果動畫。

設(shè)置
首先確保遵循了Design Support Library的使用說明唾糯。

浮動操作按鈕與Snackbar
CoordinatorLayout可以用來配合浮動操作按鈕的 layout_anchor 和 layout_gravity屬性創(chuàng)造出浮動效果怠硼,詳情請參見浮動操作按鈕指南。

當Snackbar在顯示的時候移怯,往往出現(xiàn)在屏幕的底部香璃。為了給Snackbar留出空間,浮動操作按鈕需要向上移動舟误。

只要使用CoordinatorLayout作為基本布局葡秒,將自動產(chǎn)生向上移動的動畫。浮動操作按鈕有一個 默認的 behavior來檢測Snackbar的添加并讓按鈕在Snackbar之上呈現(xiàn)上移與Snackbar等高的動畫嵌溢。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<android.support.design.widget.CoordinatorLayout
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.support.v7.widget.RecyclerView
android:id="@+id/rvToDoList"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>

<android.support.design.widget.FloatingActionButton
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"/>
</android.support.design.widget.CoordinatorLayout>
Toolbar的擴展與收縮

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
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.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

</android.support.design.widget.CoordinatorLayout>
響應(yīng)滾動事件
接下來,我們必須使用一個容器布局:AppBarLayout來讓Toolbar響應(yīng)滾動事件秧骑。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<android.support.design.widget.AppBarLayout
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.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

</android.support.design.widget.AppBarLayout>
注意:根據(jù)官方的谷歌文檔版确,AppBarLayout目前必須是第一個嵌套在CoordinatorLayout里面的子view(現(xiàn)在貌似不是這樣子,正確的理解是:AppBarLayout必須是CoordinatorLayout的直接子View)腿堤。

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

1
2
3
4
5
<android.support.v7.widget.RecyclerView
android:id="@+id/rvToDoList"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
當CoordinatorLayout發(fā)現(xiàn)RecyclerView中定義了這個屬性枷遂,它會搜索自己所包含的其他view,看看是否有view與這個behavior相關(guān)聯(lián)棋嘲。AppBarLayout.ScrollingViewBehavior描述了RecyclerView與AppBarLayout之間的依賴關(guān)系酒唉。RecyclerView的任意滾動事件都將觸發(fā)AppBarLayout或者AppBarLayout里面view的改變。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <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.design.widget.AppBarLayout>
app:layout_scrollFlags屬性里面必須至少啟用scroll這個flag痪伦,這樣這個view才會滾動出屏幕,否則它將一直固定在頂部雹锣⊥矗可以使用的其他flag有:

enterAlways: 一旦向上滾動這個view就可見。
enterAlwaysCollapsed: 顧名思義蕊爵,這個flag定義的是何時進入(已經(jīng)消失之后何時再次顯示)辉哥。假設(shè)你定義了一個最小高度(minHeight)同時enterAlways也定義了,那么view將在到達這個最小高度的時候開始顯示攒射,并且從這個時候開始慢慢展開醋旦,當滾動到頂部的時候展開完。
exitUntilCollapsed: 同樣顧名思義会放,這個flag時定義何時退出饲齐,當你定義了一個minHeight,這個view將在滾動到達這個最小高度的時候消失鸦概。
記住箩张,要把帶有scroll flag的view放在前面,這樣收回的view才能讓正常退出窗市,而固定的view繼續(xù)留在頂部先慷。

此時,你應(yīng)該注意到我們的Toolbar能夠響應(yīng)滾動事件了咨察。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<android.support.design.widget.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.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.CollapsingToolbarLayout>

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

通常,我們我們都是設(shè)置Toolbar的title摄狱,而現(xiàn)在脓诡,我們需要把title設(shè)置在CollapsingToolBarLayout上,而不是Toolbar媒役。

1
2
3
CollapsingToolbarLayout collapsingToolbar =
(CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
collapsingToolbar.setTitle("Title");
制造視差效果
CollapsingToolbarLayout還能讓我們做出更高級的動畫祝谚,比如在里面放一個ImageView,然后在它折疊的時候漸漸淡出酣衷。同時在用戶滾動的時候title的高度也會隨著改變交惯。

為了制造出這種效果,我們添加一個定義了app:layout_collapseMode="parallax" 屬性的ImageView。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<android.support.design.widget.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.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>
      <ImageView
          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"/>

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

自定義Behavior
在CoordinatorLayout 與浮動操作按鈕中我們討論了一個自定義behavior的例子席爽。注: 譯文http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0718/3197.html 意荤。

CoordinatorLayout的工作原理是搜索定義了CoordinatorLayout Behavior 的子view,不管是通過在xml中使用app:layout_behavior標簽還是通過在代碼中對view類使用@DefaultBehavior修飾符來添加注解只锻。當滾動發(fā)生的時候玖像,CoordinatorLayout會嘗試觸發(fā)那些聲明了依賴的子view。

要自己定義CoordinatorLayout Behavior齐饮,你需要實現(xiàn)layoutDependsOn() 和onDependentViewChanged()兩個方法捐寥。比如AppBarLayout.Behavior 就定義了這兩個關(guān)鍵方法。這個behavior用于當滾動發(fā)生的時候讓AppBarLayout發(fā)生改變祖驱。

1
2
3
4
5
6
7
8
9
10
11
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
return dependency instanceof AppBarLayout;
}

public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
// check the behavior triggered
android.support.design.widget.CoordinatorLayout.Behavior behavior = ((android.support.design.widget.CoordinatorLayout.LayoutParams) dependency.getLayoutParams()).getBehavior();
if (behavior instanceof AppBarLayout.Behavior) {
// do stuff here
}
}
理解如何實現(xiàn)這些自定義behavior的最好途徑是研究AppBarLayout.Behavior 和 FloatingActionButtion.Behavior上真。雖然這些源代碼還沒有放出來,但是你可以使用Android Studio 1.2集成的反編譯器來查看羹膳。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市根竿,隨后出現(xiàn)的幾起案子陵像,更是在濱河造成了極大的恐慌,老刑警劉巖寇壳,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件醒颖,死亡現(xiàn)場離奇詭異,居然都是意外死亡壳炎,警方通過查閱死者的電腦和手機泞歉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來匿辩,“玉大人腰耙,你說我怎么就攤上這事〔颍” “怎么了挺庞?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長稼病。 經(jīng)常有香客問我选侨,道長,這世上最難降的妖魔是什么然走? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任援制,我火速辦了婚禮,結(jié)果婚禮上芍瑞,老公的妹妹穿的比我還像新娘晨仑。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布寻歧。 她就那樣靜靜地躺著掌栅,像睡著了一般。 火紅的嫁衣襯著肌膚如雪码泛。 梳的紋絲不亂的頭發(fā)上猾封,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音噪珊,去河邊找鬼晌缘。 笑死,一個胖子當著我的面吹牛痢站,可吹牛的內(nèi)容都是我干的磷箕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼阵难,長吁一口氣:“原來是場噩夢啊……” “哼岳枷!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起呜叫,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤空繁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后朱庆,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盛泡,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年娱颊,在試婚紗的時候發(fā)現(xiàn)自己被綠了傲诵。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡箱硕,死狀恐怖拴竹,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情颅痊,我是刑警寧澤殖熟,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站斑响,受9級特大地震影響菱属,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜舰罚,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一纽门、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧营罢,春花似錦赏陵、人聲如沸饼齿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽缕溉。三九已至,卻和暖如春吃型,著一層夾襖步出監(jiān)牢的瞬間证鸥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工勤晚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留枉层,地道東北人。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓赐写,卻偏偏與公主長得像鸟蜡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子挺邀,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

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