
View的工作原理(一)——从ViewRoot和DecorView说起
前言
本文参考《Android开发艺术与探索》第四章内容及网上几篇博客,里面融入笔者的个人理解。希望能对大家理解View有所帮助。
基本概念介绍
介绍View的工作原理之前我们首先要理解DecorView和ViewRoot两个概念:
1、DecorView
DecorView是Windows中的View的最顶层View。我们可以根据下面一副图来认识它:
由这幅图我们可以看到 ,其实DecorView是一个FrameLayout,里面是一个垂直的线性布局,在线性布局中分上下两部分FrameLayout,上面一部分是TitleBar,下面是android.R.id.content,我们平常的setContentView就是将布局加载在android.R.id.content中。
2、ViewRoot
ViewRoot是连接WindowsManager和DecorView的桥梁对应于ViewRootImpl。
View的绘制流程就是从ViewRootImpl的performTraversala()方法开始的,包含三大流程:
1、Measure():[ 测量流程]
2、Layout():[布局流程]
3、Draw():[绘制流程]
这三大流程也就是View绘制的三大流程。我们可以通过下面两幅图来理解performTrarsala()方法;
什么是MeasureSpec
MeasureSpec 从名字上来看看起来是“测量规格“或是”测量说明书“。大致意思就是决定View的Measure过程。我们可以这样来理解:”MeasureSpec在很大程度上决定了一个View的尺寸规格,之所以这样说是很大程度上是因为这个过程还受父容器的影响,因为父容器影响View的MeasureSpec的创建过程。“
1、MeasureSpec
MeasureSpec代表一个32位int值,高2位代表SPecMode(测量模式),低30位代表SpecSize(在某种测量模式下的规格大小)。
SpecMode有三类如下所示:
UNSPECIFIED(未指定模式)
父容器不对View有任何限制,要多大给多大。
EXACTLY(确定模式)
父容器已检测出View所需要的精确大小,这时候View的最终大小就是SpecSize指定的值,它对应于LayoutParams中的match_parent和具体指定的数值这两种模式。
AT_MOST(最多模式)
父容器指定一个可用大小即SpecSize,View的代销不能大于这个值。对应于wrap_content。
2、MeasureSPec 和LayoutParams的对应关系
为什么要说MeasureSpec和LayoutParams对应昵?那是因为View在测量的时候会将我们设置的LayoutParams 在父容器的约束条件下 转换成MeasureSpec,然后再根据MeasureSpec来确定View测量后的宽和高。
有些读者会问:那么顶级View(DecorView)怎么转换昵?
对于顶级View:MeasureSpec有窗口尺寸和自身的LayoutParams来共同决定。
对于普通View:由父容器的MeasureSpec和自身的LayoutParams共同来决定。
通过下面一段代码我们来理解DecorView的创建MeasureSpec过程,desiredWindowWidth和desiredWindowHeight是屏幕尺寸:
我们来再看看getRootMeasureSpec方法:
在android.view.ViewRootImpl 中可以看到其对应关系LayoutParams 中这三个值在内部有个对应关系,那就是
LayoutParams.MATCH_PARENT 对应 MeasureSpec.EXACTLY
.LayoutParams.WRAP_CONTENT对应 MeasureSpec.AT_MOST
默认值(也就是具体值) 对应 MeasureSpec.EXACTLY
也就是内部只有两种模式 EXACTLY 精确模式 和 AT_MOST 最大模式!
对于普通View它的measure是由ViewGroup传递而来,我们看一下ViewGroup的measureChildWidthMargins方法:
我们可以清楚的看到子View的MeasureSpec创建与父容器的MeasureSpec和子元素本身的LayoutParams有关,此外还和VIew的margin 和 padding 有关,我们来看下ViewGroup的getChildMeasureSpec:
从上述方法中我们不难理解, 子View的MeasureSpec创建与父容器的MeasureSpec和子元素本身的LayoutParams有关。
下面一张表格对MeasureSpec和LayoutParams对应做个总结:
普通View的MeasureSpec创建规则
作者:紫雾凌寒
来源:CSDN
