近期对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的标题,以下两个颜色各自是展示和折叠时字体的颜色。
而上面的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上能找到。