Android Design Support Library使用詳解(二)

上一篇文章咱們已經學習了Snackbar,TextInputLayout、TabLayout、NavigationView、FloatingActionButton這四個MD新特性佈局。如果還沒有看的請先看下Android Design Support Library使用詳解(一),前面幾個比較簡單一點。廢話不多說,咱們接着看MD新特性的其他控件。

CoordinatorLayout

CoordinatorLayout是這次新添加的一個增強型的FrameLayout。在CoordinatorLayout中,我們可以在FrameLayout的基礎上完成很多新的操作。
主要功能:

  • 作爲頂層佈局
  • 調度協調子佈局

目前這個框架提供了幾種不用寫動畫代碼就能工作的方法,這些效果包括:

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

這裏寫圖片描述

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

這裏寫圖片描述

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

這裏寫圖片描述

CoordinatorLayout與FloatingActionButton
當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>

FloatingActionButton是最簡單的使用CoordinatorLayout的例子,FloatingActionButton默認使用FloatingActionButton.Behavior。

CoordinatorLayout與AppBarLayout
AppBarLayout嵌套TabLayout
佈局文件代碼:

<?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"
    android:id="@+id/main_content"
    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"
        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"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_scrollFlags="scroll|enterAlways" />

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

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

    <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="end|bottom"
        android:layout_margin="@dimen/fab_margin"
        android:src="@drawable/ic_done" />

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

效果:
這裏寫圖片描述

效果顯示,視圖滾動時,Toolbar會隱藏,這個效果是Android Support Library裏面,新增的CoordinatorLayout, AppBarLayout實現的。通過AppBarLayout的子視圖的屬性控制。觀察AppBarLayout的子佈局,Toobar有app:layout_scrollFlags屬性,這就是控制滑動時視圖效果的屬性。app:layout_scrollFlags有四個值:

  • scroll: 所有想滾動出屏幕的view都需要設置這個flag, 沒有設置這個flag的view將被固定在屏幕頂部。例如,TabLayout 沒有設置這個值,將會停留在屏幕頂部。
  • enterAlways: 設置這個flag時,向下的滾動都會導致該view變爲可見,啓用快速“返回模式”。
  • enterAlwaysCollapsed: 當你的視圖已經設置minHeight屬性又使用此標誌時,你的視圖只能已最小高度進入,只有當滾動視圖到達頂部時才擴大到完整高度。
  • exitUntilCollapsed: 滾動退出屏幕,最後摺疊在頂端。

爲了ToolBar可以滾動,CoordinatorLayout裏面,放一個帶有可滾動的View.如上的例子,放的是ViewPager,而ViewPager裏面是放了RecylerView的,即是可以滾動的View。CoordinatorLayout包含的子視圖中帶有滾動屬性的View需要設置app:layout_behavior屬性。例如,示例中Viewpager設置了此屬性。

app:layout_behavior="@string/appbar_scrolling_view_behavior"

爲了使得Toolbar有滑動效果,必須做到如下三點:

  1. CoordinatorLayout作爲佈局的父佈局容器。
  2. 給需要滑動的組件設置 app:layout_scrollFlags=”scroll|enterAlways” 屬性。
  3. 給滑動的組件設置app:layout_behavior屬性

CollapsingToolBarLayout

CollapsingToolBarLayout 控件可以實現當屏幕內容滾動時收縮Toolbar的效果,通常和AppBarLayout配合使用,

<?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"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="256dp"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        android:fitsSystemWindows="true">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            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="@drawable/header"
                app:layout_collapseMode="parallax"
                />

            <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"
                app:layout_collapseMode="pin" />

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

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

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:paddingTop="24dp">

            <android.support.v7.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="16dp">

                <LinearLayout
                    style="@style/Widget.CardContent"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="CardView"
                        android:textAppearance="@style/TextAppearance.AppCompat.Title" />

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="@string/card_string" />

                </LinearLayout>

            </android.support.v7.widget.CardView>
          ……
        </LinearLayout>

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

    <android.support.design.widget.FloatingActionButton
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        app:layout_anchor="@id/appbar"
        app:layout_anchorGravity="bottom|right|end"
        android:src="@drawable/ic_done"
        android:layout_margin="@dimen/fab_margin"
        android:clickable="true"/>

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

效果:

這裏寫圖片描述

這種效果在詳情頁面用的較多,展示個性化內容,圖像有強烈的吸引力。這個效果重點使用了CollapsingToolbarLayout 。
CollapsingToolbarLayout可實現Toolbar的摺疊效果。CollapsingToolbarLayout的子視圖類似與LinearLayout垂直方向排放。

CollapsingToolbarLayout 提供以下屬性和方法是用:
1. Collapsing title:ToolBar的標題,當CollapsingToolbarLayout全屏沒有摺疊時,title顯示的是大字體,在摺疊的過程中,title不斷變小到一定大小的效果。你可以調用setTitle(CharSequence)方法設置title。
2. Content scrim:ToolBar被摺疊到頂部固定時候的背景,你可以調用setContentScrim(Drawable)方法改變背景或者 在屬性中使用 app:contentScrim=”?attr/colorPrimary”來改變背景。
3. Status bar scrim:狀態欄的背景,調用方法setStatusBarScrim(Drawable)。還沒研究明白,不過這個只能在Android5.0以上系統有效果。
4. Parallax scrolling children:CollapsingToolbarLayout滑動時,子視圖的視覺差,可以通過屬性app:layout_collapseParallaxMultiplier=”0.6”改變。值de的範圍[0.0,1.0],值越大視察越大。
5. CollapseMode :子視圖的摺疊模式,在子視圖設置,有兩種“pin”:固定模式,在摺疊的時候最後固定在頂端;“parallax”:視差模式,在摺疊的時候會有個視差摺疊的效果。我們可以在佈局中使用屬性app:layout_collapseMode=”parallax”來改變。

CoordinatorLayout 還提供了一個 layout_anchor 的屬性,連同 layout_anchorGravity 一起,可以用來放置與其他視圖關聯在一起的懸浮視圖(如 FloatingActionButton)。本例中使用FloatingActionButton。

通過下面的參數設置了FloatingActionButton的位置,兩個屬性共同作用使得FAB 浮動按鈕也能摺疊消失,展現。

app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end"

使用CollapsingToolbarLayout實現摺疊效果,需要注意3點

  1. AppBarLayout的高度固定
  2. CollapsingToolbarLayout的子視圖設置layout_collapseMode屬性
  3. 關聯懸浮視圖設置app:layout_anchor,app:layout_anchorGravity屬性

自定義behavior

CoordinatorLayout功能如此強大,而他的神奇之處在於Behavior對象,CoordinatorLayout自己並不控制View,所有的控制權都在Behavior。前面寫到了FloatingActionButton.Behavior,AppBarLayout.Behavior, AppBarLayout.ScrollingViewBehavior。 AppBarLayout中有兩個Behavior,一個是拿來給它自己用的,另一個是拿來給它的兄弟結點用的。這些Behavior實現了複雜的控制功能。系統的Behavior畢竟有限,我們可以通過自定義的方式來實現自己的Behavior。

通過 CoordinatorLayout.Behavior(YourView.Behavior.class) 來定義自己的Behavior,並在layout 文件中設置 app:layout_behavior=”com.example.app.YourView$Behavior” 來達到效果。

自定義Behavior 需要重寫兩個方法:

 public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) 

 public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency)

如下面的例子,實現了點擊FloatingActionButton點擊旋轉90度,並適配Snackbar。

public class RotateBehavior  extends CoordinatorLayout.Behavior<FloatingActionButton> {
    private static final String TAG = RotateBehavior.class.getSimpleName();

    public RotateBehavior() {
    }

    public RotateBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
        return dependency instanceof Snackbar.SnackbarLayout;
    }

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
        float translationY = getFabTranslationYForSnackbar(parent, child);
        float percentComplete = -translationY / dependency.getHeight();
        child.setRotation(-90 * percentComplete);
        child.setTranslationY(translationY);
        return false;
    }

    private float getFabTranslationYForSnackbar(CoordinatorLayout parent,
                                                FloatingActionButton fab) {
        float minOffset = 0;
        final List<View> dependencies = parent.getDependencies(fab);
        for (int i = 0, z = dependencies.size(); i < z; i++) {
            final View view = dependencies.get(i);
            if (view instanceof Snackbar.SnackbarLayout && parent.doViewsOverlap(fab, view)) {
                minOffset = Math.min(minOffset,
                        ViewCompat.getTranslationY(view) - view.getHeight());
            }
        }

        return minOffset;
    }
}

佈局如下:

<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.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="@dimen/fab_margin"
        android:src="@drawable/ic_done"
        app:layout_behavior="com.meizu.coordinatorlayoutdemo.RotateBehavior"/>
</android.support.design.widget.CoordinatorLayout>

效果:

這裏寫圖片描述

參考:
android CoordinatorLayout使用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章