当Design Support Library遇上RecycleView

最近对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的滚动,都要添加这个值。

多个值使用”|”分开,比如:

layout_scrollFlags="scroll|enterAlwaysCollapsed|exitUntilCollapsed"

常见效果

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

上面我们没有指定属性,我们先来看看默认是什么效果:

由上面我们看到效果是:向上滑动全部隐藏,向下滑动到顶时两个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立即出现,看看下面效果。

上面的实现方式我们对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_第1张图片

而上面的Toolbar里我们设置了属性app:layout_collapseMode=”parallax”,这个时候置顶的并不是Toolbar,而是Title,如果需要将Toolbar置顶,需要设置属性为pin,看看效果:

还有说法enterAlwaysCollapsed跟View的minHeight有关系,尝试了一下,没发现有影响,具体有没有用还要自己尝试。另外就是 app:contentScrim=”@color/green”和app:expandedTitleMarginStart=”50dp”两个属性,前者代表折叠起来时置顶View的背景,后者则表示标题刚上折叠时起始位置相对于左边的间距。如果我们将app:expandedTitleMarginStart设为5dp,则红色的Title初始位置会在现在位置的左边。

上面就是Design Support Library与RecycleView组合使用的介绍,图中的例子在我的Github上能找到。

你可能感兴趣的:(layout,AppBar,Android新组件,RecyclView)