一看就懂的View测量过程介绍
来源:互联网 发布:尼泊尔少年 知乎 编辑:程序博客网 时间:2024/05/19 04:51
Android系统将屏幕上的UI组件抽象为View,并组织成树状结构,以便管理。一个View在屏幕上显示时,要先测量,从而确定自己的大小。网上各种讲解测量的文章,在我看来,都不够好,有的失于浅显无法揭露本质,有的堆砌源码,对初学者不友好。本文试图避免上述两个缺点,让初学者能够真正掌握View的测量过程。
要钱
view的测量过程,就是它与其父view沟通的过程,类似于小孩向家长要钱的过程,不同的小孩要钱的方式不一样。
儿子要钱的请求封装在LayoutParams中,主要指里面的width和height。父亲开的价封装在widthMeasureSpec和heightMeasureSpec中,里面包括一个mode和一个size。mode代表父亲的大方程度,size表示父亲最后给的钱数。为简便起见,本文分析width的确定过程。
1. 目标明确的小孩。
小孩:爸,我要十块钱。(width = 10)
父亲:(看看自己有没有)好,给你十块钱,拿去花吧儿子。 (mode = Exactly size = 10)
2. 贪心的小孩。
小孩:爸,你有多少钱我要多少钱。(width = match parent)
父亲:(看看自己还有8块)儿子,老爸总共只有8块钱了,全给你。 (mode = Atmost 或Exactly size = 8)
对于贪心的小孩,父亲给的钱既是最多的(Atmost),也是精确的(Exactly),具体用哪个mode都可以。最后的size就是父亲的所有钱。
3. 乖乖的小孩
小孩:爸,我不要多少钱,只要够我每天给小丽买零食就好了。(width = wrap content)
父亲:(心里嘀咕:这儿子真乖,可是到底该给他多少呢,算了,毕竟是亲生儿子,干脆有多少给多少吧)儿子,老爸所有的钱都给你,你看着花吧。(mode = Atmost size = 10)
另外,对于上述三种要钱的小孩,如果父亲是土豪,完全可以用一种方法回复儿子,那就是:随便花!此时的mode就是Unspecified。
小孩:(嘿嘿,会卖乖的小孩才有钱花呀)
花钱
子view通过上述三种方式之一,拿到了父view给的钱(即widthMeasureSpec) ,这些钱到底怎么花呢?也就是说,子view怎么通过父view给的widthMeasureSpec来确定自己的尺寸呢?过程如下:
1、数数父亲给的钱。 儿子:先来看看老爹最后给了多少钱。
(下面代码为伪代码)
mode = getMode(widthMeasureSpec);size = getSize(widthMeasureSpec);
2、看看自己至少得花多少钱。
儿子:先看看至少得花多少钱,调用我的getSuggestedMinimumWidth方法。
(下面代码为伪代码)
miniWidth = getSuggestedMinimumWidth()
3、确定花多少钱
儿子:根据我的至少得花的钱和父亲给的钱,确定我花多少钱。调用我的getDefaultSize方法。(下面代码为伪代码)
getDefaultSize(miniWidth,widthMeasureSpec){ //result就是儿子最后要花的钱。 int result = miniWidth; int mode = getMode(widthMeasureSpec); int size = getSize(widthMeasureSpec); switch (mode) { /*老爹说了,我不管你要多少钱,你自己看着花就是。作为一个懂事的儿子,必须学会给老爹省钱啊,只花最少的钱就是了。*/ case Unspecified: break; /*老爹如果给我他所有的钱(Atmost),那我就全花了,(真 是 败 家 儿 子 !)如果给的钱是确定的(Exactly),那就给多少花多少吧。*/ case AT_MOST: case EXACTLY: result = size; break; } return result; }
4、开始花钱
儿子:好了,我要开始花钱了,好开心呦!!调用我的setMeasuredDimension方法。
setMeasuredDimension(result);//就是上面得到的result啦!
好了,上面的4个步骤统一到了一个onMeasure方法中。如下所示:(伪代码)
void onMeasure(int widthMeasureSpec) { setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec)); }
学完上面的知识,我们发现这个儿子有点言行不一啊!当他向父亲提出要够花的钱时(wrap content),父亲把所有的钱都给了他(Atmost),结果这个败家儿子,把钱全花了(请看上面的getDefaultSize方法)。如果我们自定义一个儿子,让他言行一致,就要改写getDefaultSize方法,让他在父亲给的钱是Atmost时,不要直接把老爹的钱(size)全花了。具体怎么改写呢?
简单讲就是,对于父亲给的钱是Atmost mode时,给result 设定一个默认值。
getDefaultSize(miniWidth,widthMeasureSpec){ //result就是儿子最后要花的钱。 int result = miniWidth; int mode = getMode(widthMeasureSpec); int size = getSize(widthMeasureSpec); switch (mode) { /*老爹说了,我不管你要多少钱,你自己看着花就是。作为一个懂事的儿子,必须学会给老爹省钱啊,只花最少的钱就是了。*/ case Unspecified: break; /*老爹如果给我他所有的钱(Atmost),那我就全花了,(真 是 败 家 儿 子 !)如果给的钱是确定的(Exactly),那就给多少花多少吧。*/ case AT_MOST://************改这里!!!!************************ //乖孩子不把父亲的钱花完,只花defaultsize的钱。 result = defaultsize ; break ; case EXACTLY: result = size; break; } return result; }
当然,还可以改写onMeasure 方法,聪明如你,一定已经知道怎么改了吧?
- 一看就懂的View测量过程介绍
- Android View的测量过程
- android view 的测量过程
- 一看就懂的自定义View -- 水波纹圆形进度球
- 一看就会Android之开发自定义的View
- Timer 的 schedule()方法 一看就懂
- 一看就懂的iOS触摸事件
- 一看就懂的ReactJs入门教程-精华版
- 一看就懂的ReactJs教程
- 一看就懂的ReactJs入门教程
- 最简单的servlet,一看就懂
- 一看就懂的css浮动详解
- 一看就懂的动态规划入门教程
- 一看就懂的ReactJs入门教程
- 一看就懂的ReactJs入门教程
- Android之View的视图测量过程
- View的测量过程学习onMeasure
- View和ViewGroup的测量过程
- MySql 出现忘记密码时 应该如何登陆?
- 动态规划方法解旅行商问题(TSP Traveling Salesperson Problem)
- HDU 1852,1452 a^n的约数和
- C++卷积神经网络实例:tiny_cnn代码详解(8)——partial_connected_layer层结构类分析(上)
- jquery ajax的使用
- 一看就懂的View测量过程介绍
- CoInitialize浅析
- <点点滴滴>Spark的调度模块和Spark容错
- 学习JAVA之路(四、java流程控制语句)
- 【持久化框架】Mybatis与Hibernate的详细对比
- send和recv函数解析
- 运行tomcat7w.exe,提示:指定的服务未安装unable to open the service tomcat7
- 【BZOJ3100】排列
- Paper Reading 4:Massively Parallel Methods for Deep Reinforcement Learning