Android M —— CoordinatorLayout

來源:互聯網
上載者:User

標籤:

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

這篇文章專門講解和CoordinatorLayout相關的知識點,這也是Design Support Library中最重要與最難的部分。

概覽

CoordinatorLayout 實現了多種Material Design中提到的滾動效果。目前這個架構提供了幾種不用寫動畫代碼就能工作的方法,這些效果包括:

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

  • 擴充或者縮小Toolbar或者頭部,讓主內容地區有更多的空間。

  • 控制哪個view應該擴充還是收縮,以及其顯示大小比例,包括視差滾動效果動畫。

設定

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

浮動操作按鈕與Snackbar

CoordinatorLayout可以用來配合浮動操作按鈕的 layout_anchor 和 layout_gravity屬性創造出浮動效果,詳情請參見浮動操作按鈕指南。

當Snackbar在顯示的時候,往往出現在螢幕的底部。為了給Snackbar留出空間,浮動操作按鈕需要向上移動。

只要使用CoordinatorLayout作為基本布局,將自動產生向上移動的動畫。浮動操作按鈕有一個 預設的 behavior來檢測Snackbar的添加並讓按鈕在Snackbar之上呈現上移與Snackbar等高的動畫。

 <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的擴充與收縮

首先需要確保你不是使用已經過時的ActionBar。務必遵循 使用ToolBar作為actionbar這篇文章的指南。同樣,這裡也需要CoordinatorLayout作為主版面配置容器。

<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>

接下來,我們必須使用一個容器布局: AppBarLayout 來讓Toolbar響應滾動事件。響應滾動事件
<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>

然後,我們需要定義AppBarLayout與滾動視圖之間的聯絡。在RecyclerView或者任意支援嵌套滾動的view比如NestedScrollView上添加app:layout_behavior。support library包含了一個特殊的字串資源@string/appbar_scrolling_view_behavior,它和AppBarLayout.ScrollingViewBehavior相匹配,用來通知AppBarLayout 這個特殊的view何時發生了滾動事件,這個behavior需要設定在觸發事件(滾動)的view之上。注意:根據官方的Google文檔,AppBarLayout目前必須是第一個嵌套在CoordinatorLayout裡面的子view。

<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">

AppBarLayout裡面定義的view只要設定了app:layout_scrollFlags屬性,就可以在RecyclerView滾動事件發生的時候被觸發:當CoordinatorLayout發現RecyclerView中定義了這個屬性,它會搜尋自己所包含的其他view,看看是否有view與這個behavior相關聯。AppBarLayout.ScrollingViewBehavior描述了RecyclerView與AppBarLayout之間的依賴關係。RecyclerView的任意滾動事件都將觸發AppBarLayout或者AppBarLayout裡面view的改變。

<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>
enterAlways: 一旦向上滾動這個view就可見。app:layout_scrollFlags屬性裡面必須至少啟用scroll這個flag,這樣這個view才會滾動出螢幕,否則它將一直固定在頂部。可以使用的其他flag有:
  • enterAlwaysCollapsed: 顧名思義,這個flag定義的是何時進入(已經消失之後何時再次顯示)。假設你定義了一個最小高度(minHeight)同時enterAlways也定義了,那麼view將在到達這個最小高度的時候開始顯示,並且從這個時候開始慢慢展開,當滾動到頂部的時候展開完。

  • exitUntilCollapsed: 同樣顧名思義,這個flag時定義何時退出,當你定義了一個minHeight,這個view將在滾動到達這個最小高度的時候消失。

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

此時,你應該注意到我們的Toolbar能夠響應滾動事件了。

回到頂部

製造摺疊效果

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

<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>

現在效果就成了:

通常,我們我們都是設定Toolbar的title,而現在,我們需要把title設定在CollapsingToolBarLayout上,而不是Toolbar。

CollapsingToolbarLayout collapsingToolbar =(CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);collapsingToolbar.setTitle("Title");

製造視差效果

回到頂部

CollapsingToolbarLayout還能讓我們做出更進階的動畫,比如在裡面放一個ImageView,然後在它摺疊的時候漸漸淡出。同時在使用者滾動的時候title的高度也會隨著改變。

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

  <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>

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

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

要自己定義CoordinatorLayout Behavior,你需要實現layoutDependsOn() 和onDependentViewChanged()兩個方法。比如AppBarLayout.Behavior 就定義了這兩個關鍵方法。這個behavior用於當滾動發生的時候讓AppBarLayout發生改變。

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    }}

理解如何?這些自訂behavior的最好途徑是研究AppBarLayout.Behavior 和 FloatingActionButtion.Behavior。雖然這些原始碼還沒有放出來,但是你可以使用Android Studio 1.2整合的反編譯器來查看。

參考:Android的材料設計相容庫(Design Support Library) 

Android M —— CoordinatorLayout

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.