乐趣区

关于android:我们为什么要自定义View

前言

或者你把握了 measure 的细节,layout 机制,事件传递机制,canvas 各种 API,然而,你们想过这个问题吗?

这一篇,不仅仅是对一个面试必会题的解析,更是透过这个问题的思考,寻找最佳实际,拓展思维角度,少走弯路。

三思系列是我最新的学习、总结模式,着重于: 问题剖析、技术积攒、视线拓展,对于三思系列。

对于 View 系列 View 系列旨在通过 对事实问题 的思考,建设欠缺的 View 体系认知,竭力倡议读者理解一下 我为什么撰写、分享这个系列。

先给出思考这个问题的 脑图,文章内容会依照思考过程开展。

思考这类问题,为什么要这样干 是最根本,作为三思系列的成员,本篇还将对以下内容点进行开展阐述:

• 怎么干 — How to do

• 是否肯定要这样干 — 实用场景

• 如果不这样干,还能够怎么干 — Best Practice

• 各种干法的 注意事项

从 View 体系呈现的目标说起

作为 GUI Graphical User Interface,图形用户接口 类型的程序 framework,View 体系是其 必不可少 的一部分。参加了两件重要的事件:

• 形容、出现 界面

• 参加 人机交互

抽象的讲,当 现有 的 View 体系内的 控件簇 无奈满足正当需要时,能够在听从 framework 外在 的 规定、机制,进行扩大,以满足需要。

从这个角度看,扩大能够有两个方面:

• 扩大 显示 性能

• 扩大 交互 性能

扩大显示性能

咱们晓得,这又分为 3 种:

1. 通过一组控件,共同完成特定的性能。

2. 扩大布局规定。

3. 扩大内容显示。

最简略的,一组控件实现特定性能

举个例子:输入框 右侧加一个 模态的图片,输入框有内容时显示,无内容时暗藏。图片显示一个❌,点击时革除输入框的内容。

通过简略的封装,咱们能够很快的实现这样的性能。

Android 的 UI 形容并不那么不便,为了不便,往往会定义一个 ViewGroup 的子类,来形容这个 控件组。然而 组合优于继承,这样的做法让人有点 膈应,不能算作是最佳实际。– 这一点对应了脑图中的 扩大类簇 1。

相比于这样干,我更倡议应用 Facade 模式 进行逻辑封装,采纳 xml 形式 申明这个控件组,或者封装 命令式构建函数构建这个控件组。

继承 ViewGroup,扩大布局规定

Android 中 ViewGroup 来封装布局规定,并提供了一套 Layout。

当这些布局规定 无奈满足 咱们的需要时,咱们能够通过 自定义 ViewGroup 的形式来实现 自定义布局规定。

当然,Android 倒退到现在,曾经 很难 找到一个绝对形象的布局规定,却没有被官网反对。

若确有必要,扩大布局规定时须要解决:

1. 封装规定形容,并实现 契约式编程设计

• 定义 LayoutParams,封装规定的细节点形容。

• 覆写 checkLayoutParams 以实现规定校验,契约式编程设计。

• 覆写 generateLayoutParams(AttributeSet attrs) 以实现 从 xml 属性生成 LayoutParams。

• 覆写 generateLayoutParams(ViewGroup.LayoutParams p) 以实现 当规定不满足契约时,生成一个满足契约的 LayoutParams,留神:能够从原 LayoutParams 中 驳回一些内容。

• 覆写 generateDefaultLayoutParams 以实现生成合乎契约的 默认布局规定,如果返回 null,在 addView(View) 时,会引起运行时异样。

2. 在 onMeasure 办法中解决测量的逻辑,以实现 确定本身大小 和 触发子 View 测量

• 承受 Parent 给到本身的 尺寸测量信息,如果测量模式是 EXACTLY,即可间接确定本身对应维度的尺寸;如果是 AT_MOST 或者 UNSPECIFIED,则须要先测量子 View,再确定本身。

• 依照布局个性,本身的 尺寸测量信息,和子 View 的布局规定属性值,确定 子 View 的 尺寸测量信息,调用 子 View 的 measure 办法触发测量。

3. 在 onLayout 办法中,解决布局,应用子 View 的 尺寸测量值 和 LayoutParams 规定值,计算子 View 的布局地位,并调用 子 View 的 layout 办法触发子 View 布局

4. 如果有特定需要,能够在 onDraw 中进行绘制,例如绘制分隔线

继承 View,扩大内容显示能力

一般来说,多数状况下,继承 View 或者 特定的 Widget 是为了扩大 布局尺寸上的个性,这根本是从 measure 机制 上动手。除此之外,一些场景下,能够通过 继承 View 实现 自定义内容绘制。

例如,显示图表的 View。

这种场景下,个别须要解决:

• 尺寸测量流程中,Content 的尺寸测量,并在 onMeasure 中实现:测量模式为 AT_MOST 或 UNSPECIFIED 时,利用 Content 的大小确定显示尺寸。

• 绘制流程中,onDraw 中实现内容的绘制。

留神: 如果并不牵涉到 交互,这并不是惟一计划,自定义 Drawable 的计划,也是很棒的计划。

借用 PhotoView 举个例子,如果交互局限为:双指缩放,拖拽,单击,双击。

那么通过 OnTouchListener + GestureDetector + 自定义 Drawable,对于绝大多数场景,都能够胜任。

4. 扩大交互性能

在这个方向上,次要还是和 事件处理 体系无关。在 View 体系 中,存在三个办法 和这个过程间接相干:

• dispatchTouchEvent

• onInterceptTouchEvent

• onTouchEvent

对于 onInterceptTouchEvent,非 ViewGroup 的 View 子类 是不参加的,因为这部分 View,曾经是事件处理的末端。

话分中间。

对于 ViewGroup

扩大的目标个别有二:

• 在失当的场景下,拦挡事件并本身解决,解决逻辑在 onTouch 中实现。

• 解决可能存在的 事件处理抵触,当然,依照 Android 的规定,利用 requestDisallowInterceptTouchEvent 能够要求 直系的 所有 Parent 不拦挡事件。但不免有意外,能够通过 onInterceptTouchEvent 来决定是否本身拦挡处理事件,或者更加简单的场景。

对于 View 而言

扩大的目标在于 定义事件的含意。

举个例子,继承 View 实现一个字母表导航控件,点击、滑动 被定义为切换到 对应的字母 进行导航。

咱们须要在 onTouchEvent 中进行解决。

在后面,咱们提到了 PhotoView 的例子,如果:事件 的含意 足够形象,例如,对 View 进行了:

  • 单击
  • 双击
  • 拖拽
  • 缩放

而不是 点击了 View 的特定区域,滑动至 View 的特定地位 等。咱们能够利用 Android 屏幕事件处理机制 中的 OnTouchListener 来获取事件信息,并进行解决。在这种做法中,利用 GestureDetector 能够大大降低这一过程的难度。

5. 总结

这一篇中,咱们比拟 随性 的思考了 为什么要自定义 View 的问题,并开展了:

• 为什么须要这么干。

• 具体做法。

• 是否有其余计划,并简略交代了 哪种计划更适宜。

这篇文章比拟短,然而这部分内容的背地,还是值得持续深究、开掘的。

最初

借此机会,在这里分享一份一线大厂 Android 中高级面试开展的残缺面试题:《2022 最新 Android 中高级面试题合集》这份材料总共【1932 页】,文末收费支付。

第一章 Android 高频面试之必考 Java 根底

1,面向对象和面向过程的区别
2,面向对象的特色有哪些
3,解释下 Java 的编译与解释并存的景象
4,简略介绍下 JVM 的内存模型
5,简略介绍下 Java 的类加载器
6,谈一下 Java 的垃圾回收,以及罕用的垃圾回收算法。
7,成员变量和局部变量的区别
8,Java 中的办法重写 (Overriding) 和办法重载 (Overload) 的含意
9,简略介绍下传递和援用传递
10,为什么重写 equals 时必须重写 hashCode 办法

11,接口和抽象类的区别和相同点是什么
12,简述下 HashMap
13,CurrentHashMap
14,介绍下什么是乐观锁、乐观锁
15,谈谈对 Java 线程的了解
16,Synchronized、volatile、Lock 并发
17,锁
18,谈谈你对 Java 反射的了解
19,注解 20,单例

第二章 Android 面试之必问 Android 根底

1,Activity:生命周期、启动模式、启动流程
2,Fragment:生命周期、与 Activity 传递数据
3, Service:启动形式、生命周期、Service 不被杀死
4,BroadcastReceiver
5,ContentProvider

6,Android View 知识点:测量流程、事件散发、MotionEvent、Draw 绘制流程等等 7,Android 过程:过程生命周期、多过程、多过程通信形式
8,序列化
9,Window
10,音讯机制:Handler 机制、工作原理
11,RecyclerView 优化:卡顿场景、其余优化策略

第三章 Android 面试之必问高级知识点

1,编译模式:AOT 长处、垃圾回收
2,类加载器:类加载器分类、双亲委托模式、Android 的类加载器
3,Android Hook
4,代码混同:Proguard、混同规定、混同模版
5,NDK:JNI 根底、NDK 开发根本流程、CMake 构建 NDK
6,动静加载:插件化、热修复

第四章 Android 面试之必问性能优化

1,启动优化:冷启动 / 热启动和温启动的优化、代码方面的优化
2,UI 渲染优化:CPU/GPU、适度绘制、解决自定义 View 的 OverDraw、Hierarchy Viewer
3,内存优化:内存治理、内存透露、大图内存优化、线上监控
4,网络优化
5,耗电优化:优化方向、耗电监控、如何监控耗电
6,安装包优化:罕用的优化策略、资源压缩、资源动静加载

第五章 Android 面试之开源库剖析

1,HTTP 与缓存实践:HTTP 缓存策略、强制缓存、比照缓存
2,OKHttp:OKHttp 申请流程、OKHttpClient、同步申请、异步申请、CacheInterceptor 网络申请缓存解决
3,Retrofit
4,Glide

第六章 算法面试题汇总

1, 排
2,二叉树
3,链表
4,栈 / 队列
5,二分搜寻
6,哈希表
7,堆 / 优先队列
8,二叉搜寻树
9,数组 / 双指针
10,贪婪
11,字符串解决
12,动静布局
13,矩阵
14,二进制 / 位运算
15,其余:两个大文件中找出独特记录、ip 地址与 int 类型的转换、整数反转、LRU 缓存策略

须要完整版《Android2021 年度的高频面试真题》的敌人能够点击这里收费支付

退出移动版