天天看點

【Material Design】CoordinatorLayout使用介紹

一、CoordinatorLayout簡介

CoordinatorLayout是Material Design 的重要元件,它作為父布局使用,可以協調(coordinate)其子布局,實作多種關聯滾動效果。本文代碼參考cheesesquare

二、基本結構

對cheesesquare中的布局代碼進行了一些修改,把幾種布局放到同一個界面上。

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.quickframe.ui.MainDrawerActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/detail_backdrop_height"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="250dp"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlwaysCollapsed|snap"
            android:minHeight="50dp"
            app:expandedTitleMarginStart="48dp"
            app:expandedTitleMarginEnd="64dp">
            <ImageView
                android:id="@+id/backdrop"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:fitsSystemWindows="true"
                android:src="@mipmap/ori"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.7"/>

            <!--app:layout_scrollFlags="scroll|enterAlways|snap"-->
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="@dimen/toolbar_height"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

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

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="@dimen/toolbar_height"
            app:tabMode="fixed"
            app:tabIndicatorHeight="@dimen/indicator_height"
            android:background="@color/white"
            app:tabIndicatorColor="@color/black"
            app:tabSelectedTextColor="@color/black"
            app:tabTextColor="@color/grey"/>

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

    <include
        layout="@layout/content_main_drawer"
        android:visibility="gone"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        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"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        app:backgroundTint="@color/grey"
        app:rippleColor="#33728dff"
        app:srcCompat="@android:drawable/ic_dialog_email"/>

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

如果對布局代碼感覺混亂或者初次接觸CoordinateLayout的話,可以看下結構圖

【Material Design】CoordinatorLayout使用介紹

紅框CoordinateLayout 父布局, 其中包含兩部分:滾動視圖和響應滾動視圖

綠框ViewPager ViewPager也可換成其它布局如FrameLayout, 重點是此布局内必須有支援嵌套滾動的view, 如RecyclerView,NestedScrollView, 目前ListView不支援嵌套滾動。

藍框AppBarLayout 響應滾動的容器布局, 當綠框中的視圖滾動時,讓AppBarLayout也産生滾動。可在其中寫入多個子view,對每個子view定義各自的響應滾動屬性,

紫框CollapsingToolbarLayout 作為AppBarLayout的子view之一,響應滾動,可折疊版的ToolBar, 可加入各種子控件如imageView, ToolBar等

灰框TabLayout AppBarLayout的子view之一, 配合ViewPager使用。

是以,CoordinateLayout主要包含了 滾動視圖 和 響應滾動視圖

三、滾動視圖

在滾動視圖ViewPager中,有一行代碼

這裡定義了滾動視圖與響應滾動視圖AppBarLayout之間的聯系。在定義了layout_behavior後,CoordinateLayout就會搜尋其子view,看是否有view和這下behavior相關聯。檢視appbar_scrolling_view_behavior的相關資訊,可以看到

<string name="appbar_scrolling_view_behavior" translatable="false">android.support.design.widget.AppBarLayout$ScrollingViewBehavior</string>
           

它其實是AppBarLayout中的一個類ScrollingViewBehavior, 實作了滾動視圖與AppBarLayout之間的聯合滾動

也就是說,我們在滾動視圖中通過layout_behavior定義一個行為behavior,作為滾動視圖與響應滾動視圖之間的聯系,就可以實作各種關聯效果,更進一步的話,可以自定義Behavior。

四、CollapsingToolbarLayout

AppBarLayout繼承自LinearLayout,布局方式為垂直,在這裡可以把它當成LinearLayout,隻是它可以讓它的子view實作響應滾動。在AppBarLayout裡我們可以通過app:layout_scrollFlags 給它的子view設定動作屬性, 上面的代碼中,CollapsingToolbarLayout作為AppBarLayout的一個子view。

先來看下scrollFlags可以設定哪些動作,它的幾個動作可以配合使用。

1. scroll: 子view如果想要滑出螢幕外,就必須設定這個flag,如果沒有設定,那子view就隻能停留在螢幕頂部。

2. enterAlways: 字面翻譯 “總是進入”,子view設定了這個動作屬性後,隻要有任意的下滑動作,就可以讓子view馬上出現

3. enterAlwaysCollapsed: 字面意思是”總是折疊進入”,是enterAlways的擴充型,需要和enterAlways一起配合使用。這個屬性一般要同時設定最小高度android:minHeight=”50dp”,也就是其折疊狀态的高度,如果在CollapsingToolbarLayout裡加了Toolbar同時設定了其高度的話,不用加上minHeight也可以實作這個屬性動作的效果。當有下滑動作時,子view會以最小高度即折疊狀态出現; 當繼續下滑,直到滾動視圖不能再滾動時,子view才會開始展開。

4. exitUntilCollapsed: 向上收縮視圖,達到最小高度時,就會消失。當CollapsingToolbarLayout中有Toolbar時,可以使Toolbar保持在最頂部。

5. snap: 23.1.0的Desing Support Library新加了snap屬性,在滾動結束時,如果view隻有部分可見,就會自動滾動到最近的邊界,確定了滾動不會在中間狀态的時候停止。

實際情況如圖

【Material Design】CoordinatorLayout使用介紹
【Material Design】CoordinatorLayout使用介紹
【Material Design】CoordinatorLayout使用介紹

CollapsingToolbarLayout是一種可折疊式的Toolbar,繼承自FrameLayout,在其中可以加入Toolbar,ImageView等各種控件,給CollapsingToolbarLayout設定了layout_scrollFlags,它就可以對其中的控件的響應滾動事件進行控件,它可以設定的屬性如下。

app:collapsedTitleGravity 折疊狀态時标題的放置布局,可以設為top, bottom, right, left, center, fill_vertical, start等。

app:expandedTitleGravity 展開狀态時标題的放置布局,設定同上。

app:collapsedTitleTextAppearance 折疊狀态時标題的樣式,可以通過style進行設定。

app:expandedTitleTextAppearance 展開狀态時标題的樣式。

app:contentScrim=”?attr/colorPrimaryDark” 折疊時的背景,當Toolbar保留在頂部時,可以通過該屬性設定Toolbar的背景,

app:expandedTitleMarginStart

app:expandedTitleMargin

app:expandedTitleMarginBottom

app:expandedTitleMarginEnd 展開狀态時标題的Margin

對于CollapsingToolbarLayout其中的控件,可以通過app:layout_collapseMode來設定折疊效果

app:layout_collapseMode=”parallax” 視覺差效果,一般配合app:layout_collapseParallaxMultiplier=”0.7”使用,視差系數為0.0~1.0。

app:layout_collapseMode=”pin” 固定模式,Toolbar設定為pin後,可以固定在頂部不被滑出。

判斷CollapsingToolbarLayout的狀态

可以通過繼承AppBarLayout.OnOffsetChangedListener進行監聽。

@Override
    public void onOffsetChanged(AppBarLayout mAppBarLayout, int verticalOffset) {
        if (verticalOffset == ) {
                    if (mState != CollapsingToolbarLayoutState.EXPANDED) {
                        mState = CollapsingToolbarLayoutState.EXPANDED;   // 修改狀态為展開
                        Log.d("state", "展開");
                    }
                } else if (Math.abs(verticalOffset) >= appBarLayout.getTotalScrollRange()) {
                    if (mState != CollapsingToolbarLayoutState.COLLAPSED) {
                        mState = CollapsingToolbarLayoutState.COLLAPSED;   // 修改狀态為折疊
                        Log.d("state", "折疊");
                    }
                } else {
                    if (mState != CollapsingToolbarLayoutState.INTERNEDIATE) {
                        mState = CollapsingToolbarLayoutState.INTERNEDIATE;  // 修改狀态為中間
                        Log.d("state", "中間");
                    }
                }
    }

    private enum CollapsingToolbarLayoutState {
        EXPANDED, COLLAPSED, INTERNEDIATE
    }
           

五、TabLayout

TabLayout用于配合Viewpager使用,可以很簡單的就實作TabPageIndicator的效果。

先看下一些基本屬性:

app:tabIndicatorHeight=”@dimen/indicator_height” 訓示條高度,想隐藏時可以直接設為0

android:background=”@color/white” TabLayout背景

app:tabIndicatorColor=”@color/black” 訓示條顔色

app:tabSelectedTextColor=”@color/black” 選中時的字型顔色

app:tabTextColor=”@color/grey” 正常字型顔色

app:tabMode=”fixed” 模式設定, fixed表示每個tab固定不會動,scrollable表示可以滑動,當有多個時,目前選中tab會一直滑動保持在螢幕正中間,除非不能再滑動。

app:tabMinWidth=”50dp” tab的最小寬度

app:tabGravity=”fill” 可以設定fill或center,fill時tab均分填滿,center時,當tab較少時,隻擠在中間。

app:tabTextAppearance=”@style/TabLayoutTextStyle” 可以在style中設定字型樣式,比如字型大小。

使用的話,有幾種方式

1、直接綁定viewpager

mFragmentAdapter = new FragmentAdapter(getSupportFragmentManager());
        mFragmentAdapter.addFragment(new RvListFragment(), "清單");
        mFragmentAdapter.addFragment(new RvGridFragment(), "網格");
        mFragmentAdapter.addFragment(new RvStagFragment(), "瀑布");
        mFragmentAdapter.addFragment(new NestCardFragment(), "卡片");
        viewPager.setAdapter(mFragmentAdapter);
        // 将TabLayout與viewpager綁定
        tabLayout.setupWithViewPager(viewPager);
           

這樣子可以直接做出上面圖檔的效果,簡單友善

2、addTab

tabLayout.addTab(tabLayout.newTab().setText("清單"));
tabLayout.addTab(tabLayout.newTab().setText("網格"));
           

或者定義後再添加

private TabLayout.Tab mTabOne;
           

3、參考官方文檔, 在布局裡添加

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

     <android.support.design.widget.TabItem
             android:text="@string/tab_text"/>

     <android.support.design.widget.TabItem
             android:icon="@drawable/ic_android"/>

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

如果想設定tab圖示的話,可以用

如果想設定tab的監聽,可以通過AddOnTabSelectedListener(OnTabSelectedListener)。

六、FloatingActionButton

基本屬性:

app:backgroundTint=”@color/grey” 背景顔色

* app:rippleColor=”#33728dff”* 點選的背景色

app:elevation=”2dp” 正常陰影大小

app:pressedTranslationZ=”4dp” 按下時的陰影大小

app:fabSize=”normal” 可選的有auto, normal和mini

關于FAB滑動隐藏和彈出子菜單的,可以參考這篇部落格以及一個第三方庫。

繼續閱讀