android 自定义view 详解(二)

发布时间:2026/10/10 15:07:29

android 自定义view 详解(二) 一、View 绘制流程1. View 的绘制流程是什么measure/layout/draw 分别做什么measure测量 View 的宽高从根 View 递归调用measure()→onMeasure()结果存在mMeasuredWidth/Heightlayout确定 View 的位置调用layout()→onLayout()子 View 一般在这里调用child.layout()draw绘制内容调用draw()→ 依次执行drawBackground→onDraw→dispatchDraw→onDrawForeground2. MeasureSpec 是什么三种模式有什么区别模式值含义EXACTLY1精确值如match_parent或具体数值AT_MOST2最大值如wrap_contentUNSPECIFIED0无限制如 ScrollView 中的子 View3. 为什么onMeasure会执行多次父 View 可能多次测量子 View 以确定最终尺寸典型的如RelativeLayout、LinearLayout的权重分配4.getWidth()和getMeasuredWidth()的区别getMeasuredWidth()measure 阶段获取的原始测量值getWidth()layout 阶段确定的最终宽度mRight - mLeft通常两者相等但在某些自定义布局中可能不同二、自定义 View 的分类与选择5. 自定义 View 有哪些实现方式如何选择方式适用场景特点继承 View完全自定义绘制重写onDraw无子 View继承 ViewGroup自定义布局重写onLayout管理子 View 位置继承已有 View扩展功能如继承 TextView 增加新属性继承已有 ViewGroup组合控件如继承 FrameLayout 封装复杂 UI6. 自定义 View 如何支持wrap_content必须在onMeasure中处理AT_MOST模式否则wrap_content效果等同于match_parent示例javaif (widthMode MeasureSpec.AT_MOST) { widthSize desiredWidth; }三、触摸事件分发高频考点7. 事件分发的三个核心方法dispatchTouchEvent分发事件返回 true 表示消费onInterceptTouchEventViewGroup 专属是否拦截事件onTouchEvent处理事件8. 事件传递顺序plainActivity.dispatchTouchEvent → PhoneWindow.DecorView.dispatchTouchEvent → ViewGroup.dispatchTouchEvent → onInterceptTouchEvent返回 true 则拦截调用自己的 onTouchEvent → 不拦截则传给子 View → 子 View 的 dispatchTouchEvent → onTouchEvent9. 如果子 View 不消费事件事件会怎么处理子 View 的onTouchEvent返回 false → 事件回传给父 View 的onTouchEvent如果所有 View 都不消费最终回传给 Activity 的onTouchEvent10.requestDisallowInterceptTouchEvent的作用子 View 调用此方法可以阻止父 View 拦截事件常用于解决 ScrollView 嵌套 RecyclerView 的滑动冲突四、自定义绘制11.onDraw中常用的 Canvas API 有哪些绘制基础图形drawLine、drawRect、drawCircle、drawOval、drawArc绘制文字drawText绘制路径drawPath绘制图片drawBitmap12. Paint 常用属性setColor/setARGB颜色setStrokeWidth描边宽度setStyleFILL填充、STROKE描边、FILL_AND_STROKEsetAntiAlias抗锯齿setTextSize文字大小13. Path 的使用场景绘制贝塞尔曲线、复杂形状moveTo、lineTo、quadTo二阶贝塞尔、cubicTo三阶贝塞尔addArc、addCircle等添加基本图形14.Canvas.save()和Canvas.restore()的作用save()保存当前 Canvas 状态坐标系、裁剪区域等restore()恢复到上一次 save 的状态常用于临时变换坐标系后恢复五、动画15. Android 动画的分类类型实现方式特点补间动画View AnimationAlphaAnimation、TranslateAnimation等只改变视觉效果不改变实际属性属性动画Property AnimationValueAnimator、ObjectAnimator真正改变属性值更灵活帧动画Drawable AnimationAnimationDrawable逐帧播放图片16. 属性动画的原理通过ValueAnimator在时间内计算插值利用反射或setter方法不断更新目标属性底层依赖Choreographer的VSync信号驱动17. 自定义 View 中如何实现属性动画定义属性对应的setter方法使用ObjectAnimator.ofFloat(view, propertyName, values...)或者使用ValueAnimatorAnimatorUpdateListener手动更新六、性能优化18. 自定义 View 有哪些性能优化手段避免在onDraw中创建对象应提前初始化 Paint、Path 等使用clipRect和quickReject减少不必要的绘制区域开启硬件加速setLayerType(View.LAYER_TYPE_HARDWARE, null)使用invalidate(Rect)局部刷新而非全屏刷新避免过度绘制减少重叠区域的绘制次数19. 什么是双缓冲自定义 View 中如何利用双缓冲在内存中先绘制到 Bitmap再一次性绘制到屏幕自定义 View 中可通过setLayerType或手动使用离屏 Bitmap 实现20.invalidate()和requestLayout()的区别invalidate()触发重绘调用onDraw不改变尺寸requestLayout()触发重新测量和布局调用onMeasure→onLayout七、其他细节问题21. 自定义属性attrs如何定义和使用在res/values/attrs.xml中定义declare-styleable在构造方法中通过TypedArray获取属性值记得typedArray.recycle()回收22. 自定义 View 的三个构造方法分别什么时候调用一参代码中new View(context)二参XML 中使用三参XML 中使用 指定 style四参API 21XML 中使用 指定 theme attribute23.postInvalidate()和invalidate()的区别invalidate()必须在 UI 线程调用postInvalidate()内部通过 Handler 投递到 UI 线程可在子线程调用24. 如何解决自定义 View 的内存泄漏及时移除动画监听和 Handler 回调避免在onDraw中创建大量临时对象页面销毁时停止动画八、实战场景题25. 如何实现一个圆形进度条思路继承 View在onDraw中用drawArc绘制背景圆弧和进度圆弧通过属性动画更新进度值调用invalidate重绘26. 如何实现一个可拖拽的 View在onTouchEvent中处理ACTION_DOWN、ACTION_MOVE、ACTION_UPACTION_MOVE时计算偏移量调用layout()或offsetLeftAndRight()更新位置或使用ViewDragHelper更推荐27. 如何实现一个折线图/柱状图计算坐标映射关系使用Path连接数据点考虑边缘 padding、动画过渡效果
延伸阅读

更多相关文章

2026/10/11 1:56:42

3.Qt中容器类型的控件

1. QWidget关于QWidget在前面的章节中已经介绍过了, 这个类是所有窗口类的父类, 可以作为独立窗口使用, 也可以内嵌到其它窗口中使用。Qt中的所有控件都属于窗口类, 因此这个类也是所有控件类的基类。如果一个窗口中还有子窗口, 为了让子窗口有序排列&am…

2026/10/11 1:57:40

Python断点调试终极指南

于其中设置断点的办法存有多种, 涵盖运用pdb模块, 包含集成开发环境也即IDE像或的断点功能, 以及借助代码里的调试语句 以下是其中一种办法的详尽描述:采用pdb模块乃是最为根本且最为灵动的方式, 能于代码里插入pdb; pdb.(), 此情形会在程序运行至该行之际暂停执行, 进而步入交…

2026/10/9 18:17:54

Python查map()用法?按住Ctrl点一下,瞬间惊呆

讲解高阶函数 map() 的具体应用方式。1、 在中创建一个新文件。2、 于输入map( )之后, 按住Ctrl这个按键继而点击map, 能够查看内置模块, 会发觉map( )事实上是某类, 并且其名称的首字母是小写的, 不合乎通常拟定名称的习惯。3、 有众多类包含于内置模块之中, 像常见的 int() 呀…

2026/10/11 1:57:29

医疗健康EMBA:投入成本、服务边界与长期合作价值

医疗健康EMBA的价值判断与选择维度 医疗健康领域的管理者在进修选择上,往往面临投入成本、服务边界与长期合作价值之间的权衡。判断是否适合某一项目,不能仅看品牌知名度,而应聚焦于课程设计是否匹配当前的职业阶段与组织需求。本文将从成本、…

2026/10/11 1:57:29

Kubeadm配置kubelet cgroup驱动实操

Kubeadm配置kubelet cgroup驱动实操技术栈:Kubernetes v1.32.13 Rocky Linux 8.6 Containerd 1.7.x Calico v3.27.x操作环境 / 对接原理 / 详细步骤 / 完整命令 / 配置文件 / 验证流程 / 排错方案Kubeadm配置kubelet cgroup驱动实操操作环境K8s 集群版本 v1.32.1…

2026/10/11 1:57:29

一文讲透|2026年最值得信赖的专业AI论文平台

2026年AI论文写作工具已从“内容生成”进化为多维度学术支持系统,核心评价维度包括文献真实性、格式合规性、长文本逻辑、查重降重及AIGC合规性。本次测评覆盖6款主流工具,涵盖中英文、全流程与专项功能、免费与付费版本,让你快速锁定最适合的…

2026/10/11 1:57:29

K8S- Master节点扩容加入集群实操

Kubeadm Master节点扩容加入集群实操技术栈:Kubernetes v1.32.13 Rocky Linux 8.6 Containerd 1.7.x Calico v3.27.x操作环境 / 对接原理 / 详细步骤 / 完整命令 / 配置文件 / 验证流程 / 排错方案Kubeadm Master节点扩容加入集群实操操作环境K8s 集群版本 v1.32…

2026/10/11 1:52:29

.NET 4.5.2 WPF公式编辑器核心实现:LaTeX解析与GlyphRun自绘排版

简介:这是一份可直接运行的C# WPF数学公式编辑器完整工程,基于.NET Framework 4.5.2构建,主要面向希望深入WPF桌面应用开发的学习者,也适用于教育、科研与论文排版中有公式编辑需求的用户。项目实现了公式输入、LaTeX/MathML解析与…

2026/10/11 0:02:13

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/11 0:02:13

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/11 0:02:13

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/11 0:02:13

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/11 0:02:13

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/11 0:02:13

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑