记录了我前不久实现的一个效果,并逐步分析了使用到各个控件的使用方式,可能有点啰嗦,还请见谅。
前一段时间公司有个需求,就是要实现成微博客户端发现模块的效果,先放一个效果图看一下吧。
录制的不是太好,大家见谅(可以打开微博看一下效果),大概这个效果就是,在ViewPager之上,有一个可伸缩的头部,在头部完全隐藏的时候,使其不可下拉,点击返回键之后,再显示出头部来。
分析
微博的效果给人的感觉是整个页面在头部隐藏之后,会抖动一下,就像是新开了一个页面一样。当时第一反应就是,这个东西可以利用CoordinatorLayout+AppBarLayout来实现这个功能。
说干就干……开始吧……
过程
提到CoordinatorLayout,想必大部分朋友是知道的,这里我再啰嗦点叙述一遍吧,CoordinatorLayout是Google伴随着Material Design推出的一个可自定义布局伸缩的控件。常见的有知乎App的效果:当内容滑动时,顶部的ActionBar随之隐藏。
当然还有一些比较不错的效果,比如一些转换的效果,网上一大堆,这里就不再叙述了。
本文中使用的另外一个“主角”,就是AppBarLayout了。
我在这里直接介绍AppBarLayout的 app:layout_scrollFlags 属性吧,这个属性是加在AppBarLayout的子View上的,有以下几种flag:
-
scroll:增加了这个flag之后,View会伴随着滚动滑出屏幕。
-
enterAlways:这个flag就是,当你的View已经隐藏的时候,例如向上滚动顶部的View已经不可见了,设置了这个属性之后,当你向下滚动的时候,View会随着掉下来,而不是说滚动到顶部之后才能拉下来隐藏的View。
-
exitUntilCollapsed:这个flag就是当你为View定义了一个最小值之后,View之后收缩到最小值大小,例如你设置了一个5dp的高度,那么当View滑动到只有5dp那么高的时候,便不再收缩了。
-
enterAlwaysCollapsed:与上面的flag对立,表示何时以最小值进入。
- snap:说起这个flag就很有意思了,这一套东西,其实为的就是解决嵌套滑动的问题,而这其中有一个bug,那就是滑动极其不顺畅。当你向上滑动想要隐藏顶部的AppBarLayout的时候,可能会遇到一次滑不上去,过程十分卡顿。当你向下滑动想要拉出顶部的AppBarLayout的时候,有的时候又要用特别大的力气,这个flag算上Google的一个弥补吧。那就是,当你滑动到50%左右的时候,帮你隐藏显示,这样看上去效果是流畅了,却又变得怪怪的了。
具体效果大家自己写一遍就可以看到了,也不难。
(关于AppBarLayout伸缩卡顿的问题,我是通过判断RecyclerView是否滑动到顶部来解决的)
OK,简单的了解完了我们要使用的两个控件,下面就是代码部分:
首先是布局:
<!-- 最外层是支持嵌套滑动的CoordinatorLayout -->
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:theme="@style/MainAppBar"
android:background="@color/colorPrimaryDark"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- app:layout_scrollFlags="scroll|exitUntilCollapsed"
设置当前view随滚动伸缩 -->
<LinearLayout
android:id="@+id/ll_header_layout"
android:orientation="vertical"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:layout_width="match_parent"
android:layout_height="@dimen/header_height"
android:background="@color/colorPrimaryDark" />
</android.support.design.widget.AppBarLayout>
<!-- 这个viewpager则是触发滚动的view,每一项可以设置为recyclerview的fragment,
别忘了要加这段话:app:layout_behavior="@string/appbar_scrolling_view_behavior" -->
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
在尺寸的资源文件里面加上 header layout 的高度。