最近对Design Support Library中的一些新组件做了些研究,其中涉及到CoordinatorLayout、AppBarLayout、CollapsingToolbarLayout,为了突出这些View的效果,我们使用Toolbar实现标题栏,还要借助RecycleView实现列表,这篇博客的代码在我的Github可以找到。其中遇到了很多问题,我也会分享出来,避免大家再次“入坑”。
父类是ViewGroup,这个View的作用相当于一个容器,放在最顶层,借助于Behaviors,可以简单的实现容器里View之间的交互。
一般和可以滑动的View比如RecycleView或ListView之类的配合放在CoordinatorLayout容器中使用,通过参数的配置,RecycleView的滑动事件可以被AppBarLayout感知到。
作为AppBarLayout的子标签使用,对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"
我们自定义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>
我们自定义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的效果,现在使用原生控件也是分分钟的事,这就得用到另一个组件了—— 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的标题,下面两个颜色分别是展示和折叠时字体的颜色。
而上面的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上能找到。