430aae732a80512f10b94ae49b49ba49
重学安卓:从 0 到 1 “自定义视图” 完整爬坑顺序

往期回顾专栏目录更新动态优惠政策版权须知

温馨提示:如果这是第一次接触《重学安卓》,可通过上述链接来访问和快速了解《重学安卓》专栏、获取它的目录、试读内容,以及了解它的最新动态 和 发展状况。

截至目前,专栏已对 体系化文章 做了 1970 余次修订,数十位群友告诉我 受专栏的启发 他们也开启了写作之路。群里不定期会有小伙伴讨论适配问题、分享原创的开源库 和 提供内推机会,订阅后可随时进群交流。

·

Note 2021.5.25 重要提示

阅读本文的最佳时机是,您已吃过 阅读 “源码” 或 “源码分析文” 时 找不到头绪的苦

您还没吃过苦,那您先不要着急阅读本文。您得吃过苦,才会有体会。

在您吃够这方面的苦后,您才有机会发现,本文正是专用于解决 “如何选择和归类自定义控件” 的困扰。

我们 绝不通篇贴源码,而是基于广泛的实践和反思,在累积过大量样本 乃至足以排除掉所有干扰信息后,点到为止地揭露 “视图交互 乃至 产品设计” 最为核心的本质,方便您理解背后的底层逻辑,乃至可以笃信地 选择或实现合适的自定义控件在项目中使用。

前言

在过去的几个月中,我们分别 深入浅出地复盘了 视图控制器的 生命周期、重建机制、状态管理、页面通信、路由导航,以及作为 标准化开发模式的 Jetpack MVVM 最佳实践

相信经过几个月的实践、反思和沉淀,小伙伴们对作为 “应用开发骨架” 的 “视图控制器” 及其 “标准化开发框架” 已胸有成竹。

本来随后我是想直接开讲自定义视图,但如果像其他网文一样,一上来就介绍细枝末节的技术点,那恐怕会很让人感到沮丧,找不到支点来立足和展开。

并且值得注意的是,自定义视图学习的切入点,并不全在技术领域内

因此,在正式开讲自定义视图的技术知识之前,我决定 通过这样一篇 “导读” 来做个预热,方便小伙伴们对后续章节具体内容的学习。

文章目录一览

  • 前言
  • 死记硬背时期 的混沌世界
  • 深度思考眼中 的自定义视图
    • 对现存自定义视图的学习
    • 对视图标准化 API 的学习
  • 综上
  • Note 2021.08.15 加餐:
    • 从 0 到 1 “自定义视图” 完整爬坑顺序
  • Note 2020.07.07 加餐:
    • 重学安卓 开源库 内部共享计划

死记硬背时期 的混沌世界

记得刚参加工作不久的时候,我也和多数人一样,思维还停留在 学生时代 死记硬背的水平,老想着 大而全、蛇吞象,想把所有东西都整理好、强迫自己记下来。

最初我的策略是,将控件 按覆盖面积 分类,例如 导航类、表单类、展示类、容器类,等等。然后不断地收集关于它们的第三方库、Google 自家控件的知识点等等。

一开始是有一点效果,知道控件怎么用,但也就到这种程度为止,过一段时间,便通通遗忘。

更糟糕的是,这种 不科学的管理方式,使得对控件的管理逐渐失控,每当有新的控件被我相中时,我却不知道将其归类到哪个目录下为好。

我相信很多人都有过这样的经历,最开始十分努力,后来不了了之

有的人从此开启了咸鱼模式,反正这也学不好,那也学不好,干脆得过且过、混吃等死。另有的人则是加倍努力,然后背下来的知识,也加倍地忘记 …

那么有多少人真的反思过,是不是自己的思考方式出了问题呢

由于时间过去了太久,我不想展开介绍 从死记硬背 到深度思考,这期间我究竟经历了些什么,乃至于有了这样的领悟。但正如你们看到的,前面几期关于视图控制和 MVVM 深入浅出的介绍,都是来自深度思考的结果。

深度思考 不一定能带来 绝对正确的结论,但却一定是自恰的、能让自己信服从而义无反顾地行动

深度思考的精髓就在于 探究为什么、探究事物存在的缘由。凡事把这个想明白,就能透过现象抓住本质。(详见 《基本功:是随时随地可受用的 深度思考原则》 篇的解析)

深度思考眼中的自定义视图

所以,在形成了深度思考的习惯后,我对视图的学习,也发生了翻天覆地的变化。

不再是一上来就 死记硬背是什么 和 练习怎么用。

而是首先思考,自定义视图 为什么存在?(凡是 View 的实现类,都算自定义视图,不要觉得 Google 默认实现的就不算、只有自己实现的才算)

视图的存在,对用户来说,是为了满足 所见即所得 的人机交互需求;对开发者来说,是为了能够定制视图 来提供合适的用户体验。

换言之,

若不是为了满足用户 对 所见即所得 的需求,视图根本不需要存在,给个黑底白字的命令行就行了。

若不是为了让开发者 能够定制视图 来提供合适的用户体验,视图也不需要通过 模版方法模式 和 组合模式 来 设计出标准化的 API、供开发者定制、并且由 统一的视图管理机制 在后台运筹帷幄

所以至此,我们发掘并确立了视图的两大学习方向:

1.对现存自定义视图的学习

如果你想掌握 市面上已有的 自定义视图,例如 RecyclerView,那么 务必结合用户使用场景、从用户体验的角度去思考:为什么产品交互 要设计成这个样子、为什么要通过 RecyclerView 去实现,为什么会提供像 SnapHelper 这种接口。

唯有如此,你才有机会真正 想明白并且掌握 关于 RecyclerView 的一切。像 LayoutManager、ItemDecoration、LayoutAnimation 乃至后来的 DiffUtil、SnapHelper,它们的存在 绝非一蹴而就,绝不是死记硬背 能够消化的,除了追根溯源到 产品设计、思考业务场景,没有别的路能走 —— 这条看似曲线救国,实则最快达成目的的学习路线。

例如 第三方库 LayoutManagerGroup 提供的这 6 种场景实现,如基于 “死记硬背” 时期的不科学分类 ,就很难分清楚

由于 产品设计 铺陈开来讲,不花个 30 篇下不来,所以本专栏不会展开介绍 “产品设计” 以及 “现存自定义视图”,

不过我们决定在《滑动冲突》篇,借着 “滑动冲突” 的场景,来解析 “产品设计” 的通用底层逻辑,相信读者阅读完会耳目一新。

具体详见《滑动冲突 的快乐你不懂!》 篇提供的示范。

2.对视图标准化 API 的学习

也即通常人们所说的 “自定义控件” 的学习。

相比对 现存自定义视图的学习,我觉得这个要更容易掌握一些,毕竟既然支持自定义,就务必是标准化的、基于模版方法模式的实现,因而 接口都是统一的、可预测、可掌握的,绝非扑朔迷离的

学习标准化 API,无非就是去掌握 视图的 排版和触控(人机交互就这两样)。所以在接下来的章节中,我们会分别介绍 排版和触控 所依赖的 坐标系统、属性参数、事件分发机制、滑动冲突处理、视图绘制 等等。

综上

视图不仅仅是技术领域的知识,更是产品领域的知识。

只有想明白了用户使用场景,才能想明白 现存自定义视图 及其 技术点 的存在缘由。

自定义控件,不过是基于系统提供的标准化 API,去满足 特殊用户使用场景 的需求。

最后,这里站在产品设计的角度 分享一个屡试不爽的信条:

用户体验的目标之一,就是洞悉用户的意图,最大限度地让操作连贯、避免被打断。(详见下一篇 《滑动冲突 的快乐你不懂!》 对这条原则全网独家的解析)

所以平日里要 多多思考和学习 头部软件的产品设计,例如张小龙的微信(比如 为什么 朋友圈发动态的 “所在位置” 不要 展示地图,而聊天消息中的 “发送位置” 展示地图呢?)

并且,在同类场景中 尽量照搬这些 普适的设计,从而减少用户的学习成本。只有在万不得已的情况下,才考虑自己去设计和实现控件,否则费力不讨好

便捷链接:

基本功:是随时随地可受用的 深度思考原则

GitHub : 重学安卓 配套项目

GitHub : Jetpack-MVVM-Best-Practice

视图系列文章:

重学安卓:滑动冲突 的快乐你不懂!

重学安卓:不如我们 从零开始设计一套 视图系统

重学安卓:百闻不如一见的 视图系统 架构全貌

top Created with Sketch.