仿写豆瓣详情页(一)开篇

6,897 阅读3分钟

仿写豆瓣详情页(一)开篇
仿写豆瓣详情页(二)底部浮层
仿写豆瓣详情页(三)内容列表
仿写豆瓣详情页(四)弹性布局
仿写豆瓣详情页(五)联动和其他细节

1、初衷

首先,从用户体验的角度来说,豆瓣各个页面内容的滑动和衔接都十分顺滑,这一点十分佩服豆瓣的产品和开发。而豆瓣的详情页是我接触过的 UI 中动画最复杂的,因此一直想尝试实现一下。

另一方面也希望提升下自己处理复杂交互动画的能力。日常需求的交互都比较简单,也不涉及复杂的动画,或者有现成的组件可以用。事件分发和嵌套滑动只是大体了解,还需要多加实践。

半年前的时候尝试实现过一次,由于时间和精力的原因中途放弃,这次决定坚持搞下去,至少有个像样的 demo。

2、页面结构拆分

复杂的功能可以通过分层来解决,复杂的 UI 也可以拆成一小部分一小部分相对简单的 UI 来实现。这里根据我自己的观察(毕竟我也拿不到豆瓣的源码,而且实现方案也是多种多样的),将页面的主要结构拆成不同的部分,并对每一部分抽象成业务无关的 View,在此基础上实现豆瓣的页面效果。

2.1、底部弹起浮层

查看动图

CoordinatorLayout 有一个 BottomSheetBehavior 实现的就是这个效果。其实自己实现也很简单,方式也有多种,这里就自己造一个简单的轮子。

2.2、内容列表

查看动图

这部分的视图「看起来」是一个大列表,里面有影片的信息(这里以电视剧为例)、豆瓣评分、剧情介绍、演职员表、剧照、短评和其他等卡片。下面还塞了影评的视图,由一个剧评和小组讨论两个 tab 页面(暂不考虑自己的影评部分)组成,里面的内容是一个列表。

然后是交互。在我们不断上滑的过程中,先是列表内容向下滚动,滚动到底部后,开始滚动影评的列表部分;手指下滑时,列表向上滚动,先滚动影评的列表部分,再滚动外层的大列表。

对于这样的 UI,我首先想到的就是 NestedScrollView,的确可以用这个实现,但是会有很多问题,这个会在下面的文章中细说。

2.3、弹性布局

查看动图

「演职员表」和「剧照」是两个水平滚动的列表,左右两侧滚动到头都会有弹性的效果,在右侧滑倒一定程度松开会打开下一级页面。

当然 github 上也有很多开源的弹性视图,这里我也根据自己对事件分发和嵌套滑动的理解自己造了个轮子。

2.4、联动和其他细节

查看动图

详情页的内容列表、底部浮层和标题栏还有联动效果。

内容底部的影评部分在还没露出时,就把这部分视图放在浮层里,滑出一部分时再从浮层中移除,放入内容列表中。

标题栏有两种状态,显示标题和显示影视信息,中间又动画过渡,状态切换随内容列表的滚动值或浮层是否完全展开而改变。

3、预备知识

  • View 的绘制流程
  • Touch 事件的分发机制
  • 嵌套滚动的分发机制,这里主要用到 NestedScrollingParent
  • 改变 View 位置的方法,margin、layout、scroll、属性动画等
  • ScrollerVelocityTracker 的用法

4、最后

最后想说的是,自定义 View 不要过于追求大而全,我们也不可能像写官方控件那样考虑各种各样的应用场景,考虑一大堆通用性和各种适配。自定义嘛,能用就行,如果总想着大而全,反而会陷入其中无法自拔。

github.com/funnywolfda…