Android 视图绘制流程完全解析,带你一步步深入了解
View( 二 )
Android 视图绘制流程完全解析,带你一步步深入了解
View( 二) 分类:
Android 疑难解析
2013-12-26 08:30
52106 人阅读
评论 (91)
收藏
举报
AndroidViewonMeasureonLayoutonDraw
目录 (?)[+]
转载请注明出处:
/guolin_blog/article/details在
上一篇文章中,我带着大家一起剖析了一下LayoutInflater
的工作原理,可以算是对View 进行深入了解的第一步吧。
那么本篇文章中,我们将继续对View 进行深入探究,看一
看它的绘制流程到底是什么样的。如果你还没有看过我的上
一篇文章,可以先去阅读Android LayoutInflater原理分析,
带你一步步深入了解
View(
一 )
。相信每个
Android
程序员
都知道,我们每天的开发工作当中都在不停地跟
View
打交
道, Android 中的任何一个布局、任何一个控件其实都是直
接或间接继承自View 的,如 TextView 、Button 、ImageView 、
ListView 等。这些控件虽然是Android 系统本身就提供好的,
我们只需要拿过来使用就可以了,但你知道它们是怎样被绘
制到屏幕上的吗?多知道一些总是没有坏处的,那么我们赶
快进入到本篇文章的正题内容吧。要知道,任何一个视图都
不可能凭空突然出现在屏幕上,它们都是要经过非常科学的
绘制流程后才能显示出来的。每一个视图的绘制过程都必须
经历三个最主要的阶段,即onMeasure() 、onLayout() 和
onDraw() ,下面我们逐个对这三个阶段展开进行探讨。一.
onMeasure()measure是测量的意思,那么onMeasure() 方
法顾名思义就是用于测量视图的大小的。 View 系统的绘制流程会从 ViewRoot 的 performTraversals() 方法中开始,在其内部调用 View 的 measure() 方法。 measure() 方法接收两个参数, widthMeasureSpec 和 heightMeasureSpec ,这两个值分别用于确定视图的宽度和高度的规格和大小。
MeasureSpec的值由 specSize和 specMode共同组成的,
其中 specSize记录的是大小,specMode记录的是规格。
specMode一共有三种类型,如下所示:
1. EXACTLY表示父视图希望子视图的大小应该是由
specSize的值来决定的, 系统默认会按照这个规则来设置子
视图的大小,开发人员当然也可以按照自己的意愿设置成任
意的大小。 2. AT_MOST表示子视图最多只能是specSize
中指定的大小,开发人员应该尽可能小得去设置这个视图,
并且保证不会超过specSize 。系统默认会按照这个规则来设
置子视图的大小,开发人员当然也可以按照自己的意愿设置
成任意的大小。 3. UNSPECIFIED表示开发人员可以将视图
按照自己的意愿设置成任意的大小,没有任何限制。这种情
况比较少见,不太会用到。那么你可能会有疑问了,
widthMeasureSpec和 heightMeasureSpec这两个值又是从
哪里得到的呢?通常情况下,这两个值都是由父视图经过计
算后传递给子视图的,说明父视图会在一定程度上决定子视
图的大小。但是最外层的根视图,它的widthMeasureSpec
和 heightMeasureSpec 又是从哪里得到的呢?这就需要去
分析 ViewRoot中的源码了,观察performTraversals()方法
可以发现如下代码:[java] view
plaincopychildWidthMeasureSpec =
getRootMeasureSpec(desiredWindowWidth, lp.width);
childHeightMeasureSpec =
getRootMeasureSpec(desiredWindowHeight, lp.height);
可以看到,这里调用了getRootMeasureSpec()方法去获取
widthMeasureSpec和 heightMeasureSpec的值,注意方法
中传入的参数, 其中 lp.width 和 lp.height 在创建 ViewGroup
实例的时候就被赋值了,它们都等于MATCH_PARENT。然