摘要

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

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

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

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

compile 'com.android.support:design:23.1.0'

AppBarLayout:本质上是一个垂直的线性布局。但是他实现了材料设计中app bar的滚动手势的特性。而为了让这些特性发挥效果,你必须把AppBarLayout作为CoordinatorLayout的一个直接子控件来使用。并且,你还需要为AppBarLayout设置一个支持NestedScroll的兄弟控件。这样父控件CoordinateLayout就知道什么时候来响应滚动事件了 它的子控件可以通过setScrollFlags(int)或者app:layout_scrollFlags的方式来为自己指定滚动行为。可选的行为有:SCROLL_FLAG_ENTER_ALWAYS、SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED、SCROLL_FLAG_EXIT_UNTIL_COLLAPSED、SCROLL_FLAG_SCROLL、SCROLL_FLAG_SNAP。

CoordinateLayout:本质上是一个增强版的FrameLayout。一般作为一个容器来使用,这样可以让它的子控件实现一些交互效果。可以通过给子控件指定不同的Behaviors来实现不同的交互效果。

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

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:layout_width="match_parent"

android:layout_height="wrap_content"

android:theme="@style/AppTheme.AppBarOverlay">

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:id="@+id/recycler_view"

android:layout_width="match_parent"

android:layout_height="wrap_content"

app:layout_behavior="@string/appbar_scrolling_view_behavior" />

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

其实,就改这么点地方就可以了。想要的效果已经有了。不信给你看看效果图。

9aee8783feb2

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

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

9aee8783feb2

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

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

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

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:layout_width="match_parent"

android:layout_height="wrap_content"

android:theme="@style/AppTheme.AppBarOverlay">

android:layout_width="match_parent"

android:layout_height="240dp"

app:collapsedTitleGravity="center"

app:contentScrim="@color/colorPrimary"

app:layout_scrollFlags="scroll|exitUntilCollapsed">

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:scaleType="centerCrop"

android:src="@drawable/cheese_1"

app:layout_collapseMode="parallax" />

android:id="@+id/toolbar"

android:layout_width="match_parent"

android:layout_height="?attr/actionBarSize"

app:layout_collapseMode="pin"

app:popupTheme="@style/AppTheme.PopupOverlay" />

android:id="@+id/recycler_view"

android:layout_width="match_parent"

android:layout_height="wrap_content"

app:layout_behavior="@string/appbar_scrolling_view_behavior" />

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

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

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

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

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐