C 端 5.8.0 开发迭代的时候,产品需求中有个投票模块。其交互效果是模仿新浪微博的投票器,感觉挺有意思,动画效果也不错,便在需求拆分的时候认领了过来。
2 难点分析
认领后得着手赶紧去实现,因为这个自定义控件后续的业务需求等着用,观察了新浪的投票效果分析出如下难点:
1 复合动画
拆解动画得出一共存在三种动画组合在一起表达
a : 投票文字的平移动画
b: 投票数从无到有的透明度渐变动画
c: 投票柱状图进度动画
2 大 view 组合控制小 view
假定投票器的选项可能为 N 种,这里需要做动态的生成每个小 view ,以成以及大 View 能通知 N 个小 view 做对应的状态变化
不能提前得知 N 的具体数值,也就不能提前知道有几个小 view ,如何对每个小 view 做通知以及他们的点击事件如何处理?
3 多状态处理 以及 列表中滑动复用问题的处理
投票控件有投票未投票状态,每个小 view 中还存在小 view 的选中状态和非选中状态,包括
在后来的实际列表滑动中的复用问题产生多个 view 以及动画重复播放的问题如何解决?
3 设计思路
见上方简略类图,定义两个重要的角色
1 VoteSubView : 它是具体的投票项,职责是负责三种复合动画(平移、渐变、进度条)的开始与结束以及 View 的选中状态数据与 UI 的绑定,同时它实现了接口 VoteObserver 。每个被实例化出来的 VoteSubView 作为观察者观察 Subject 发布者的通知变化(Notify),它与 VoteView 是聚合关系 (Aggregation)。
2 VoteView : VoteView 是投票器整体本身,它聚合了 N 个 (投票选项)VoteSubView,职责是封装对外提供调用 API 接口(外界对 VoteSubView 是不可见的 ),包括投票器的监听、投票状态、初始化等。同事它也是事件的发布者,当外界有行为操作投票器时,它将发布动作。观察者 VoteSubView 对此做相应的状态变化。
上述是 VoteSubView 和 VoteView 的关系设定以及代码设计,核心使用的设计模式是观察者模,因为投票项可能是 N 个项,外界操作其中某一项其他项都需要及时的得知变化, 个人认为当期的需求场景下使用此模式是比较恰当的。
关于动画当时有两种方案,1 使用自定义 View 2 使用 Android API 提供的 animation 动画。
自定义 view 肯定能实现,只是实现的成本以及实现出来的质量(卡顿,多 item 等),对自定义控件技术要求过高,综合考虑 deadline 最终选用了 Android animation API 接口实现
这里只需要对 Android 动画有一定程度的掌握,可能用较小的成本实现这个需求,实际的开发过程中良好的技术选型节约开发时间也是我们需要掌握的。
使用复盘: 实际使用的时候,自定义控件在列表中多个 item/cell 出现,包括下拉刷新的时候,出现了一系列的包括
1 产生了多个投票重复的子 view
2 item/cell 复用时重复动画
3 数据投票状态 + 选中状态不一致(状态与数据同步)
的问题花费了不少时间,其中有一些可以在架构设计的时候考虑进去的话能够做到提前避免,这是以后需要注意的地方
4 延伸思考
1 如果将上述的投票器改成多选,该怎么设计?
2 如果采用自定义 View 去实现三种复合动画效果怎么实现?
源码: https://github.com/13120241790/VoteView