ListView或者RecycleView滚动时隐藏Toolbar( Part 2 )

ListView或者RecycleView滚动时隐藏Toolbar( Part 2 )

> * 原文链接 : How to hide/show Toolbar when list is scrolling (part 2) * 译者 : chaossss * 校对者: 这里校对者的github用户名 * 状态 : 完成

Hello,各位小伙伴,俺胡汉三又来了!!!今天我打算接着上一篇博文继续给大家讲解展现/隐藏Toolbar的效果。我建议没有读过 ListView或者RecycleView滚动时隐藏Toolbar 这篇文章的小伙伴先去看看那篇博文再来看这篇博文,不然会跟不上我的讲解节奏的哦。在上一篇博文里,我们学习了如何去实现Google+那个酷炫的展现/隐藏Toolbar的效果,今天,我将会给大家讲解怎么让上一篇博文的效果进化成Google Play Store Toolbar那样,废话不多说,我们现在进入正题吧:

在我们开始之前,我想先告诉大家的是我已经对这个项目进行了一些重构——我继承项目的 MainActivity 实现了两个新的子类:PartOneActivity 和 PartTwoActivity。源码在包 partone 和 parttwo里,你可以在这两个包里挑选你喜欢的那一个使用

下面是我们的最终效果图,我把它和 Google Play Store Toolbar 放在一起比较,大家可以感受一下:

准备工作

在这里我不会再给大家展示 build.gradle 文件,因为这和第一部分的 build.gradle 文件是一样的,所以我们将会从这个步骤开始——为我们的Activity创建一个layout:

同样的,layout里面只有一个 RecyclerView 和一个 Toolbar (稍后再加上 Tabs)。值得注意的是,我这里的实现是使用之前说的第二种方法(为RecyclerView添加Padding)

同样的道理,由于我们的布局文件、list、RecyclerAdapter 都和之前是一样的,我在这里都不会再给大家讲解了。

那现在我们来看看 PartTwoAcitivty 的代码吧:

在 PartTwoActivty 里面仍然是简单地对 RecyclerView 和 Toolbar 进行初始化,但大家一定要记得设置 OnScrollListener 哦(第27行)

感觉大家看到这里也感觉昏昏欲睡了,因为前面提到的内容大体上都和上一篇相似。但是莫慌!俺接下来就要讲这篇博文中最有趣的部分 —— HidingScrollListener 了,请大家紧紧抱住我,跟上节奏!

如果你看过第一篇博文可能会觉得此情此景很熟悉(可能还会感觉简单一些)。我们在 HidingScrollListener 里耍了什么 tricks 呢?那就是存了与 Toolbar 的高度相关联的屏幕滚动偏移量 —— mToolbarOffset。为了简化其中的逻辑,只有当 mToolbarOffset 的取值在[0 , Toolbar的高度]之间时,我们才会实现我们的逻辑:当我们向上滚动时,mToolbarOffset的值会增加(但不会超过Toolbar的高度);当我们向下滚动时,mToolbarOffset 的值会减少(但不会低于0)。大家现在可能会有许多疑问:为什么要引用 mToolbarOffset 呀?为什么要让 mToolbarOffset 的取值范围介于那两者之间呐?别怕!你马上就会理解为什么我们要这样限制mToolbarOffset的取值了。我们必须知道的是,尽管我们极力去避免意外的发生,但现实总会出人意料,在这里也不例外,有时候 mToolbarOffset 的值就是会不可避免地在我们的取值范围之外,但由于我们的逻辑设计的限制,最终的显示效果会是闪烁一下。(例如:在屏幕上快速的挥动、滑动)这样的结果显然不是我们这些有格调的 Android 工程师想要的,因而我们需要对 mToolbarOffset 进行一定程度的裁剪,以规避这样的风险。基于这样的考虑,我们重载了 onMoved()方法 —— onMoved() 方法是一个当我们滚动视图时被调用的抽象方法。可能会吓到你,但是莫慌,继续抱住我!

接下来,我们就要回到我们 PartTwoActivity 设计之中,并且在我们的滚动监听器中实现 onMoved()方法。

是的,这就是所有内容啦。我们运行 App 后可以看到我们的最终效果:

是不是感觉自己棒棒哒~就像我们想象的那样,Toolbar 完美的随着list的滚动实现了展现/隐藏的效果。其中的功劳都得归功于我们对 mToolbarOffset 取值范围的限制。如果我们省略掉检查 mToolbarOffset 是否在[0 , Toolbar的高度]范围中取值的过程,带着完成控件的喜悦向上滚动我们的list,Toolbar 确实会如你所期望的那样离开屏幕,但与此同时,Toolbar 还会远远地,远远地,离开视图,再也不回来。然后当你满是期许地向下滚动时,你就会发现刚刚那一声再见,竟是永远。如果你想再次遇见它,你就必须想下滚动,直到 mToolbarOffset = 0。

再脑补第二种情况吧,现在你正好把 Toolbar 滚动到 mToolbarHeight = mToolbarOffset 的位置,不偏不倚。那么现在Toolbar就刚好“坐”在了list顶部,如果你向上滚动的话,无论你怎么滚,它都不会动,只会静静地坐在那儿笑看人世沧桑。而如果你向下滚动,它又成为许多年前那个明亮、可爱的小女孩了。

虽然最终的实现效果看起来非常赞,但这并不是我想要的。因为我们能在滚动过程中停止整个效果,使得 Toolbar 有一部分是可见的,另一部分又是不可见的。但悲伤的是,Google Play Games 就是这么干的,而我一直认为这是一个Bug……

在某一点停下 Toolbar

就我的认知来说,我认为滚动的Views是能够如丝般顺滑地对齐相应的位置的,就像 Chrome 应用里的 Logo/SearchBar 又或者是 Google Play Store应用里那样。我很确定我在 Material Design 的guidelines/checklist 或者是 以前听过的Google I/O 大会上听过类似的规范。

那我们现在再来看看 HidingScrollListener 的代码吧:

虽然为了实现上面提到的效果我们会让 HidingScrollListener 的代码变得更复杂一些,但是我再说一次,莫慌,抱紧我!我们现在只需要重载 RecyclerView.onScrollListener 类的 onScrollStateChanged()方法,然后按照下面那样干就行了:

首先,我们需要检查list是否处于 RecyclerView.SCROLL_STATE_IDLE 状态,以确保list没有在滚动或者挥动(因为如果list如果正在滚动或者挥动的时候,我们就需要像第一篇博文那样去考虑 Toolbar 的Y方向位置哦)

一个人的天地是冷得连呼吸都会寂寞的颤栗,而麻烦,

ListView或者RecycleView滚动时隐藏Toolbar( Part 2 )

相关文章:

你感兴趣的文章:

标签云: