天天看點

當Design Support Library遇上RecycleView新添加的元件Toolbar的配置互動原理常見效果實作Parallax效果

最近對Design Support Library中的一些新元件做了些研究,其中涉及到CoordinatorLayout、AppBarLayout、CollapsingToolbarLayout,為了突出這些View的效果,我們使用Toolbar實作标題欄,還要借助RecycleView實作清單,這篇部落格的代碼在我的Github可以找到。其中遇到了很多問題,我也會分享出來,避免大家再次“入坑”。

新添加的元件

1. CoordinatorLayout

父類是ViewGroup,這個View的作用相當于一個容器,放在最頂層,借助于Behaviors,可以簡單的實作容器裡View之間的互動。

2. AppBarLayout

一般和可以滑動的View比如RecycleView或ListView之類的配合放在CoordinatorLayout容器中使用,通過參數的配置,RecycleView的滑動事件可以被AppBarLayout感覺到。

3. CollapsingToolbarLayout

作為AppBarLayout的子标簽使用,對Toolbar進行了包裝,使Toolbar可以折疊起來。

Toolbar的配置

說到Toolbar,首先要設定好樣式,這裡注意不能是Actionbar,是以主題不要帶Actionbar,不然會報異常。

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>
           

接着我們的Activity必須繼承AppCompatActivity,然後就是對Toolbar的一些設定。

setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });
           

互動原理

我們前面說了,CoordinatorLayout裡的不同子View之間是可以互動的,那怎麼樣才能讓他們互動起來呢?我們在滑動的View比如RecycleView标簽下添加”app:layout_behavior=”@string/appbar_scrolling_view_behavior”“,其與AppBarLayout.ScrollingViewBehavior相對應,

用來通知AppBarLayout滑動的View發生了滾動事件,而當CoordinatorLayout發現RecycleView設定了此屬性後,就會去查找自己的子View裡有沒有添加app:layout_scrollFlags屬性,有此屬性的就會被通知。

而上面的app:layout_scrollFlags屬性有以下幾種方式:

1. enterAlways:向下滑動時,即使沒有滑動到頂部的CollapsingToolbarLayout,CollapsingToolbarLayout也會立刻出現。

2. enterAlwaysCollapsed:向下滑動時,隻有滑動到頂部的CollapsingToolbarLayout時,CollapsingToolbarLayout才會顯示出來。

3. exitUntilCollapsed:向上滾動View時,Toolbar或Title會固定在上面。

4. scroll:這個屬性隻要是想收到RecycleView的滾動,都要添加這個值。

多個值使用”|”分開,比如:

常見效果

效果1 —— 預設效果

我們自定義MyView(這裡是TextView),添加Toolbar,然後下面是一個RecycleView,布局如下:

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:title="AppBarLayout"
            android:background="@color/white"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_scrollFlags="scroll"/>

        <TextView
            android:padding="15dp"
            android:text="這是可以向上滾動隐藏的TextView"
            android:background="@color/gold"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll" />
    </android.support.design.widget.AppBarLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycleview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

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

上面我們沒有指定屬性,我們先來看看預設是什麼效果:

當Design Support Library遇上RecycleView新添加的元件Toolbar的配置互動原理常見效果實作Parallax效果

由上面我們看到效果是:向上滑動全部隐藏,向下滑動到頂時兩個View才出來,是以預設效果跟下面代碼一樣:

<android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:title="AppBarLayout"
            android:background="@color/white"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_scrollFlags="scroll|enterAlwaysCollapsed"/>

        <TextView
            android:padding="15dp"
            android:text="這是可以向上滾動隐藏的TextView"
            android:background="@color/gold"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|enterAlwaysCollapsed" />
    </android.support.design.widget.AppBarLayout>
           

效果2 —— 向下滑動時立即出現

我們自定義MyView,當我們向上滑動時,Toolbar和MyView隐藏,向下滑動時,Toolbar緊随MyView立即出現,看看下面效果。

當Design Support Library遇上RecycleView新添加的元件Toolbar的配置互動原理常見效果實作Parallax效果

上面的實作方式我們對Toolbar為app:layout_scrollFlags屬性設定了enterAlways,向下滑動時MyView和Toolbar都會立即出現。

<android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:title="AppBarLayout"
            android:background="@color/white"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_scrollFlags="scroll|enterAlways"/>

        <TextView
            android:padding="15dp"
            android:text="這是可以向上滾動隐藏的TextView"
            android:background="@color/gold"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|enterAlways" />
    </android.support.design.widget.AppBarLayout>
           

實作Parallax效果

有時候我們需要出現parallax的效果,現在使用原生控件也是分分鐘的事,這就得用到另一個元件了—— android.support.design.widget.CollapsingToolbarLayout,我們看看怎麼使用:

CollapsingToolbarLayout也是直接作為AppBarLayout的子控件使用的,而CollapsingToolbarLayout裡可以定義Toolbar和自定義的View,看下面的布局檔案:

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:theme="@style/ThemeOverlay.AppCompat.ActionBar">
        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:fitsSystemWindows="true"
            app:contentScrim="@color/green"
            app:expandedTitleMarginStart="50dp"
            app:layout_scrollFlags="scroll|enterAlwaysCollapsed|exitUntilCollapsed">

            <ImageView
                android:id="@+id/imageView"
                android:layout_width="match_parent"
                android:layout_height="300dp"
                android:scaleType="fitXY"
                android:background="@mipmap/title"
                android:minHeight="5dp" />

            <!-- 設定layout_collapseMode為pin時,收縮為ToolBar,
                 而為parallax時,隻收縮為Title -->

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.7">
            </android.support.v7.widget.Toolbar>

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

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycleview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

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

而在代碼裡,我們也需要對CollapsingToolbarLayout做些處理,代碼如下:

collapsingToolbarLayout.setCollapsedTitleTextColor(
                getResources().getColor(R.color.black));
        collapsingToolbarLayout.setExpandedTitleColor(
                getResources().getColor(R.color.red));
           

這裡有一點需要注意:我們對Toolbar設定标題是沒用的,必須通過CollapsingToolbarLayout設定Toolbar的标題,下面兩個顔色分别是展示和折疊時字型的顔色。

當Design Support Library遇上RecycleView新添加的元件Toolbar的配置互動原理常見效果實作Parallax效果

而上面的Toolbar裡我們設定了屬性app:layout_collapseMode=”parallax”,這個時候置頂的并不是Toolbar,而是Title,如果需要将Toolbar置頂,需要設定屬性為pin,看看效果:

當Design Support Library遇上RecycleView新添加的元件Toolbar的配置互動原理常見效果實作Parallax效果

還有說法enterAlwaysCollapsed跟View的minHeight有關系,嘗試了一下,沒發現有影響,具體有沒有用還要自己嘗試。另外就是 app:contentScrim=”@color/green”和app:expandedTitleMarginStart=”50dp”兩個屬性,前者代表折疊起來時置頂View的背景,後者則表示标題剛上折疊時起始位置相對于左邊的間距。如果我們将app:expandedTitleMarginStart設為5dp,則紅色的Title初始位置會在現在位置的左邊。

上面就是Design Support Library與RecycleView組合使用的介紹,圖中的例子在我的Github上能找到。

繼續閱讀