怎么使用Toolbar之给Toolbar加上动画

摘要

通过上一篇文章我们初次认识了下Toolbar。聊了下怎么把Toolbar集成到项目中和Toolbar的基本设置这两个问题。接下来聊聊怎么给Toolbar加上一些交互效果,类似Play商店上的那些效果。

效果一:使Toolbar随着内容区域的滚动而隐藏和显示

我们知道手机屏幕的大小时候限的,有时候我们为了显示更多的内容需要隐藏掉一些不相关的内容,比如Toolbar。以前我们可能会使用属性动画或者通过view.animate().translationXX()这个便捷的方法来实现这些效果。现在就不用这么麻烦了,只需要在xml中添加两行代码就可以了。

为了实现上述的效果,这里需要引入两个新的控件:CoordinatorLayoutAppBarLayout,这两个控件均位于design兼容包中。所以你需要在module的build.gradle依赖中加入下面一行代码。

1
compile 'com.android.support:design:23.1.0'
  • AppBarLayout:本质上是一个垂直的线性布局。但是他实现了材料设计中app bar的滚动手势的特性。而为了让这些特性发挥效果,你必须把AppBarLayout作为CoordinatorLayout的一个直接子控件来使用。并且,你还需要为AppBarLayout设置一个支持NestedScroll的兄弟控件。这样父控件CoordinateLayout就知道什么时候来响应滚动事件了 它的子控件可以通过setScrollFlags(int)或者app:layout_scrollFlags的方式来为自己指定滚动行为。可选的行为有:SCROLL_FLAG_ENTER_ALWAYSSCROLL_FLAG_ENTER_ALWAYS_COLLAPSED
    SCROLL_FLAG_EXIT_UNTIL_COLLAPSEDSCROLL_FLAG_SCROLLSCROLL_FLAG_SNAP
  • CoordinateLayout:本质上是一个增强版的FrameLayout。一般作为一个容器来使用,这样可以让它的子控件实现一些交互效果。可以通过给子控件指定不同的Behaviors来实现不同的交互效果。

扯了这么多好像也没啥感觉,感觉还真是“Talk is cheap. Show me the code.”呢。那下来就撸代码,看效果吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.demo.activity.MainActivity">


<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">


<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay"/>


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

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


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

上面的布局中有两个地方需要注意:1.Toolbar的app:layout_scrollFlags="scroll|enterAlways"属性 2.RecyclerView的app:layout_behavior="@string/appbar_scrolling_view_behavior"属性。这两个地方就是上文中加粗部分的提到的注意点。同时,注意下整个布局的结构:CoordinateLayout作为跟布局,内部分别放置了一个AppBarLayout和RecyclerView。Toolbar作为AppBarLayout的子控件而存在。
其实,就改这么点地方就可以了。想要的效果已经有了。不信给你看看效果图。

效果二:多个控件协同作战(其实没想出来怎么描述这种效果)

这种效果我还不好描述,直接上图一看你就明白。一图顶千言啊!

从上面的效果图中可以看到,随着内容区域的滑动顶部的图片和Toolbar也会做出相应的动作。图片会收缩和展开,Toolbar的背景在透明和蓝色之间变化。要实现这种类似Play商店的效果,还需要引入一个新的控件:CollapsingToolbarLayout。该控件同样位于design兼容包中。

CollapsingToolbarLayout是对Toolbar的包装,它实现了可收缩的app bar效果,而且被设计为AppBarLayout的直接子类来使用的。

引入CollapsingToolbarLayout控件后,我的布局变成了这样子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.demo.activity.MainActivity">


<android.support.design.widget.AppBarLayout

android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">


<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="240dp"
app:collapsedTitleGravity="center"
app:contentScrim="@color/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">


<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="@drawable/cheese_1"
app:layout_collapseMode="parallax" />


<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/AppTheme.PopupOverlay" />

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

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


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

可以看到,Toolbar被CollapsingToolbarLayout包裹起来了,并且给Toolbar添加了一个ImageView的兄弟控件。同时在CollapsingToolbarLayout的子控件上分别设置了app:layout_collapseMode属性(姑且就叫收缩模式吧),该属性有两种值:parallax和pin。parallax属性值会让的CollapsingToolbarLayout子控件在滚动时呈现出视差效果,而pin则会让它的子控件保持不动。从上面设置的值对比着效果图看,应该就比较清晰了。

CollapsingToolbarLayout有很多属性可以控制滚动过程中文字的滚动轨迹,文字样式,文字的位置以及它的子控件之间的配合方式。比如collapsedTitleGravity可以设置收缩结束时title的对其方式,上例中使用了居中对齐,所以title最终显示在了toolbar的中间,默认是靠左显示的。

其实之前提到的这些新控件配合起来可以实现的效果还是挺多的,这里面有一个起到重要角色的对象:Behavior。它定义了CoordinateLayout的子控件之间的交互行为,如果想实现一些自定义的交互效果,那么就需要自己去实现一些Behavior了。关于Behavior的自定义目前还不太了解,以后有机会的话也会研究下。

这篇就说这么多吧,计划下一篇把CollapsingToolbarLayout的那些属性总结下,然后再搞下Android抽屉的用法。