自定义控件那些事儿 ----- 二

本文详细介绍自定义控件的绘制流程,包括Measure、Layout和Draw三个关键步骤,并探讨了如何通过合理布局减少过度绘制的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、引述

上一篇自定义控件那些事儿 ----- 一 说明了自定义控件实现的五个步骤:

(1)View属性的初始化;

(2)View位置大小的量测 ,主要在onMeasure()中实现;

【(3)View内部的布局关系展示,主要在onLayout()中实现;】

(4)View的绘制,即是最后的展示效果;

【(5)View交互事件的处理,实现View与目标对象的沟通。】


并且上一篇文章中,应用必要的环节完成一个简单的自定义控件,熟悉整个流程。同时也弄清楚,自定义控件实现中,主要大的框架实现有以下五部分:

(1)自定义控件的属性设置及对应值的获取;

(2)onMeasure()的实现;

(3)onLayout()的实现;

(4)onDraw()的实现;

(5)交互事件的实现,onTouchEvent()、以及ClickListener等监听器的处理。


没有很好的系统规划,进入职业疲乏期一样,除了保持基本的工作,保持基本的学习进度。最近的一年多并没有给自己增加较大的压力。所幸一切都还在基本的往前推进,自定义控件 ----- 属性与组合控件 都详细介绍了属性的设置值类型及获取值的方式。因此,第一部分也就算已经往前推进了。【若是有交流沟通与优化建议,希望听到大家的声音】


推荐一篇博客,Android应用层View绘制流程及源码分析,详细的分析拆解了基于源码分析的View绘制绘制流程。也是基于这篇博客,我做一下阅读笔记,并理解形成自己对于自定义控件的理解记忆。


二、主体框架

如文章描述,一个Activity页面的页面展示如图所示:


ContentView和TitleActionBar共同构成了一个Activity的整体布局。所以,必须先设置是否无Title模式,再设置ContentView才能够实现自定义头部布局的样式。已经设置ContentView后也就设置了TitleActionBar的显示模式。


1、Measure过程


依据博文,了解整个量测过程。在博客中说明比较清晰,我才用实际的例子再来拆解理解一下。

在View展示的最后模式中,View中主要用于展示一张图片,或者显示一些文字,加上实际内容(图片/文字)与其他控件之间的间距,从而形成整个展示效果。


如图,一个手机屏幕内展示一个View A 和一张图片,View A需要包含图片在内部。


手机屏幕的根View肯定是match_parent的,也就相当于根View的宽高等同于屏幕的宽高。

View量测模式有以下三种:

MeasureSpec.EXACTLY //确定模式,父View希望子View的大小是确定的,由specSize决定;
MeasureSpec.AT_MOST //最多模式,父View希望子View的大小最多是specSize指定的值;
MeasureSpec.UNSPECIFIED //未指定模式,父View完全依据子View的设计值来决定; 
对于指定View宽高也就相当于:固定大小,match_parent,wrap_content。

在实际的填充内容中,最终包裹的有效内容是图片或者文字,都会设置一定的大小。图片有图片的原始大小,文字有设置文字大小、间距、长度等,这些间接的设置了包裹文字的view的初始化大小。

如图所示,仅是View A和一张图片,有以下展示效果:



(1)View A设置包裹内容的时候,最后展示的效果,图片浮与View A的表面,两个一样大小。

(2)View A设置宽填充父窗体的时候,如图中间所示,能够显示相对大小关系;

(3)View A设置固定大小时,在固定大小大于图片大小时,和包裹内容相似;在固定大小小于图片大小时,图片会被缩小显示。这时候会取决于图片的缩放模式,从而显示不同的内容。


综上描述,整个量测过程确定了每个View的大小。


2、Layout过程


如博客所描述,以上图片是整个View的布局过程。

经过Measure过程,已经确定了每个View的大小,但即使是已经量测大小的View A 和 图片,他们最终展示的效果依旧有很多的变化。


如图:

(1)包裹内容下,View A和图片的大小已经确认,而二者的结合体在根View的展示位置却并未唯一标识下来。通过Layout布局,就可以确定是上图顶部的左还是右。

(2)在match_parent的模式下,View A的位置已经固定,但图片在View A中的位置却并未唯一。同样可以有左右的样式甚至更多。


通过整个Layout过程,就能够将每个View的位置唯一固定下来。


3,Draw过程


经过以上两步,每个View的大小、位置均固定下来。没有绘制,不展示出来,还依旧没什么用!通过整个绘制流程将所有内容展示出来。


在开发者选项中打开过度绘制,会发现每个view都绘制完善了,所以在view的叠合部分,绘制了很多次。因此,合适的布局及较少的布局叠加层次也是很重要的。



三、后续规划

通过以上的内容,对整个view的绘制流程有了较为清晰地认识。但每个阶段的实际执行却并没有很深入。在绘制展示完成后,并没有结束所有的工作。APP是需要能够和用户交互的。用户在手机屏幕上的动作,需要做对应的响应,分解到View上也就是对事件的响应。

接下来,对自定义控件这一块学习有以下的规划。

1,详解三大步骤,对其内容进行深度挖掘;

2,交互事件的处理,交互模式下新的绘制流程控制;

3,基于以上内容的学习,进行相关内容的扩展;

(如绘制流程,扩展paint,canvas)

4,自定义控件的实例实现,拆解,强化整个流程;

5,基于以上模式并不能完全理解Adapter模式,并结合设计者模式加以理解、深化。


莫急莫急,流程图的Axture原件在这里!






巴拉巴拉拉:


人生维艰,哪有什么胜利可言,挺住就是一切。


如果一定要有方法,那就是守住崩溃的底线,时刻保持对死亡的畏惧。可以对活着丧失一切的期许,但一定要尊重生命。


基于html+python+Apriori 算法、SVD(奇异值分解)的电影推荐算法+源码+项目文档+算法解析+数据集,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档 电影推荐算法:Apriori 算法、SVD(奇异值分解)推荐算法 电影、用户可视化 电影、用户管理 数据统计 SVD 推荐 根据电影打分进行推荐 使用 svd 模型计算用户对未评分的电影打分,返回前 n 个打分最高的电影作为推荐结果 n = 30 for now 使用相似电影进行推荐 根据用户最喜欢的前 K 部电影,分别计算这 K 部电影的相似电影 n 部,返回 K*n 部电影进行推荐 K = 10 and n = 5 for now 根据相似用户进行推荐 获取相似用户 K 个,分别取这 K 个用户的最喜爱电影 n 部,返回 K*n 部电影进行推荐 K = 10 and n = 5 for now Redis 使用 Redis 做页面访问次数统计 缓存相似电影 在使用相似电影推荐的方式时,每次请求大概需要 6.6s(需要遍历计算与所有电影的相似度)。 将相似电影存储至 redis 中(仅存储 movie_id,拿到 movie_id 后还是从 mysql 中获取电影详细信息), 时间缩短至:93ms。 十部电影,每部存 top 5 similar movie 登录了 1-6 user并使用了推荐系统,redis 中新增了 50 部电影的 similar movie,也就是说,系统只为 6 为用户计算了共 60 部电影的相似度,其中就有10 部重复电影。 热点电影重复度还是比较高的
### Android 资源链接失败 (resource linking failed) 的错误分析与解决方案 当遇到 `Android resource linking failed` 错误时,通常是因为资源文件配置不正确或者存在冲突。以下是可能的原因以及对应的修复方法。 #### 可能原因及解决办法 1. **XML 文件中的命名空间或属性错误** 如果 XML 文件(如 `fruit_item.xml`)中定义的标签或属性不符合标准,则可能导致编译器无法解析该文件。例如,缺少必要的命名空间声明或使用了未定义的自定义属性。 确保所有 XML 文件都遵循正确的语法结构,并且包含完整的命名空间声明。如果使用的是自定义视图组件,请确认其属性已在相应的类中正确定义并注册[^1]。 2. **重复 ID 或样式名冲突** 当多个布局文件共享相同的 View ID 或者主题/样式的名称发生重叠时,也会引发此问题。检查项目内的其他地方是否有相同的名字被多次定义;如果是库依赖引入造成的冗余,则考虑通过前缀区分不同模块下的实体对象来规避此类情况的发生。 3. **缺失资源引用** 若某个控件尝试访问不存在的颜色、字符串或其他类型的资源项而未能成功找到目标数据的话,同样会抛出异常提示我们去修正这些非法操作行为。比如,在代码片段里调用了 R.drawable.image_icon ,但实际 assets/drawable 目录下并没有名为 image_icon.png 的图片素材存在就会造成上述现象出现 。此时应该核实所涉及的各项参数是否齐全有效后再重新构建工程试试看效果如何改善一些吧?另外还需注意大小写敏感度差异也可能成为诱因之一哦! 4. **Gradle 插件版本过低** 使用较旧版次 Gradle Plugin 构建新特性较多的应用程序可能会碰见兼容性方面的问题从而致使部分功能失效进而表现为 Resource Linking Failed 这样的表现形式出来给我们看到而已啦~ 更新至最新稳定发行版本往往能够很好地缓解甚至彻底消除这类麻烦事儿呢!当然记得同步调整对应 API Level 设置范围以免引起不必要的连锁反应哈~ 5. **ProGuard/R8混淆设置不当** 对于发布模式启用 Proguard 或 R8 后如果没有妥善处理保留规则就容易丢失某些必要字段而导致运行时报错显示为 Resources Not Found Exception 类型的信息窗口弹框提醒用户解决问题咯~ 修改 proguard-rules.pro 文件增加相应例外条款即可恢复正常运作状态喽! --- ```xml <!-- Example of a properly defined layout file --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/textViewFruitName" android:textSize="16sp" android:padding="8dp" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> ``` --- ### 示例代码:验证是否存在重复ID 可以通过编写简单的脚本来扫描整个项目的 res 文件夹查找潜在的风险点: ```bash #!/bin/bash find . -type f \( -name "*.xml" \) | while read FILE; do grep -Eo 'android:id="@+id/[a-zA-Z0-9_]*"' "$FILE" | sort | uniq -c | awk '$1 > 1 {print $2}' done ``` 执行以上命令可以快速定位到那些可能出现两次以上的 id 定义位置以便进一步优化改进措施落实到位减少未来再次遭遇同类事件发生的可能性几率大大降低不少哟~ --- ### 总结 通过对 `fruit_item.xml` 和相关联的部分进行全面细致地排查之后采取针对性强的有效手段逐一击破各个难关最终达成预期目的实现完美交付成果展示给客户欣赏体验一番也不错嘛😊
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

壹叁零壹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值