Android CoordinatorLayout實戰案例學習《一》

在上篇文章中,和大家一起聊了聊AppBarLayout和CoordinatorLayout兩個新控件,以及CoordinatorLayout與FloatingActionButton、Snackbar的使用注意事項。至此,Android Material Design系列的學習已進行到第五篇,大家可以點擊以下鏈接查看之前的文章:

本文繼續以案例的形式學習CoordinatorLayout的使用,配合者為AppBarLayout。文中會介紹一些這種搭配使用的案例下可能出現的問題以及解決方案,目的還是一句話,將我所知的分享出來,讓正在摸索的你少走一些彎路。老路子,先看一下本文要實現的效果圖:

Samples.gif

簡單介紹下,這種設計經常會出現在各個app中,作為主頁顯示,其中主要包含了三個效果:

  • 側拉導航菜單,這個是用v7包中的控件DrawerLayout實現的,不是本文重點,就不作過多說明了;

  • FAB與Snackbar的協調交互,在上篇文章中已經介紹的很詳細了,大家可以另行查看;

  • 列表向上滑動,Toolbar向上隱藏,TabLayout固定于頂部,給內容區域留下更多的展示空間,本文著重講述這種實現。

知識點比較零碎,還是配合著代碼講解比較容易,思路也會比較清晰一些,主要布局文件的實現:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/dl_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

        <android.support.design.widget.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <include layout="@layout/include_toolbar" />

            <android.support.design.widget.TabLayout
                android:id="@+id/tl_indicator"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

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

        <android.support.v4.view.ViewPager
            android:id="@+id/vp_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab_add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/dp_16"
            android:onClick="onClickFab"
            android:src="@mipmap/ic_toolbar_add"
            app:backgroundTint="@color/fab_ripple"
            app:layout_anchor="@id/vp_content"
            app:layout_anchorGravity="bottom|right|end" />

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

    <LinearLayout
        android:id="@+id/ll_menu"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:orientation="vertical"
        android:gravity="center"
        android:background="@color/white">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Menu Content"
            android:textColor="@color/black"
            android:textSize="@dimen/sp_16"/>

    </LinearLayout>

</android.support.v4.widget.DrawerLayout>

Android Developer官網中在介紹CoordinatorLayout時有這么一段話:

CoordinatorLayout is intended for two primary use cases:

  1. As a top-level application decor or chrome layout
  2. As a container for a specific interaction with one or more child views

也就是說CoordinatorLayout主要有兩種使用場景,在我理解過來就是,作為Activity布局中的最外層容器和作為指定交互行為的多個子控件的父容器來使用。而本文中的案例就屬于第二種。

要實現這種滑動交互效果,必須要滿足這么幾點:

  1. CoordinatorLayout作為容器布局,來協調children view之間的交互行為;

  2. 使用AppBarLayout并設置其內部需要移出屏幕的View的scrollFlags屬性,在這個例子中也就是給Toolbar設置。由于Toolbar是通用布局代碼,這里我用了include標簽,其包含的布局代碼為:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/tb_toolbar"
    android:layout_width="match_parent"
    android:layout_height="@dimen/dp_56"
    app:titleTextColor="@color/white"
    app:title="@string/app_name"
    app:theme="@style/OverFlowMenuTheme"
    app:popupTheme="@style/AppTheme"
    android:background="@color/blue"
    app:layout_scrollFlags="scroll|enterAlways"/>

可以看到,我添加了app:layout_scrollFlags這個屬性,并將其值設為scroll|enterAlwaysscroll表示滑動型控件向上滑動時toolbar將移出屏幕,enterAlways表示向下滑動時toolbar將重新進入屏幕。由于TabLayout不需要移出屏幕,所以這里就不需要給它設置這個屬性了。需要注意的是:不要將app:layout_scrollFlags屬性單獨設置子include標簽里,而是要放在include所加載的layout布局中,否則這個scrollFlags將失去作用,這與include標簽的使用有關。

  1. 一個特殊的滑動型控件并設置layout_behavior屬性,這里用的是ViewPager。注意,layout_behavior的屬性值用的是系統定義好的固定字符串@string/appbar_scrolling_view_behavior,大家感興趣的自己去翻閱源碼看看,后續介紹behavior時,我再仔細講解。

對于第三點,這里拿出來單獨強調一下,有沒有發現滑動型控件前我用了“特殊”兩個字來修飾!CoordinatorLayout之所以能夠協調Children View之間的交互行為,主要就是依賴于NestedScrolling這個東西,這里涉及到兩個接口類NestedScrollingParentNestedScrollingChild。CoordinatorLayout實現了前者,而CoordinatorLayout的Children核心之一,滑動型控件,實現了后者,所以才能夠做出這個交互行為。關于NestedScrolling,后續再寫文單獨介紹。所以,這個特殊的滑動型控件必須是實現了NestedScrollingChild接口的控件,比如v7包中的RecyclerView,看一下它的定義就知道了:

public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild

故,本文中的ViewPager里面的列表控件必須是RecyclerView。如果你僅僅是簡單地使用ListView,還是達不到這樣的效果。聰明如你,肯定又看出了我的措辭,對的,我又用了一個詞:“簡單地使用”,那就說明其實稍作處理,復雜點使用,也能夠使用ListView的。

在API Level 21及更高版本,為了支持NestedScrolling,所有控件的基類View對外新增了一個方法setNestedScrollingEnabled(boolean enabled),所以,我們可以對ListView稍作處理,就能在Android L及以上版本的系統中使用了:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
      listView.setNestedScrollingEnabled(true);
}

或者借助 v4 包中的 ViewCompat 類為 ListView 添加設置,避免版本判斷:

ViewCompat.setNestedScrollingEnabled(listView, true);

但是,這兩種方法均只支持 Android Lollipop 及更高版本,在 pre-lollipop 上是沒有效果的。其實,ListView真的已經過氣了,我們應該全方位掌握RecyclerView的使用,就像Android Studio取代Eclipse一樣。

其他的代碼就很簡單了,就是給DrawerLayout設置ActionBarDrawerToggle,就是圖中ToolBar左側的菜單按鈕。然后用Fragment填充ViewPager,這里就不貼代碼了,工程Demo都在GitHub上,大家可以自己下載參考。

其實這個案例的實現還是蠻簡單的,文中零零碎碎地講述了很多使用過程中的細節技巧,幫助大家解決實際問題。下篇文章繼續使用案例,介紹CoordinatorLayout的使用方法,同時引入另一個控件的使用,歡迎關注!

示例源碼


我在GitHub上建立了一個Repository,用來存放整個Android Material Design系列控件的學習案例,會伴隨著文章逐漸更新完善,歡迎大家補充交流,Star地址:

https://github.com/Mike-bel/MDStudySamples

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,524評論 25 708
  • 內容抽屜菜單ListViewWebViewSwitchButton按鈕點贊按鈕進度條TabLayout圖標下拉刷新...
    皇小弟閱讀 46,903評論 22 665
  • CoordinatorLayout與滾動的處理 CoordinatorLayout實現了多種Material De...
    cxm11閱讀 6,633評論 1 15
  • (文/習酒鎮?趙半仙) 樹葉被施了定身法 停在空中不說話 月亮撇撇嘴 俯視著人間的燈光 有點刺眼睛 星星啊 又偷懶...
    2632385d067a閱讀 448評論 3 14
  • 如果二婚和小孩只能選一個, 當然選小孩,小孩是專屬資產,老婆是共享資產, 小孩是一種儲蓄,老婆是一種消費, 老婆是...
    陳穩閱讀 152評論 0 0