Android中View的初步认识以及MeasureSpac的理解

View和DecorView

当Activity创建完毕时,会将DecorView添加到Window中,同时创建ViewRootImp对象,并将ViewRootImp对象与DecorView建立关联

如下代码所示:

View的绘制是从ViewRoot的performTraversals方法开始的,经过measure,layout,draw三个流程才最终将一个view绘制出来,关于这三个流程的具体情况已经在
View工作流程之Measure
View工作原理之Layout过程和Draw过程
这两篇读后感中介绍了。

这三个流程大体的调用过程可以用一张图来总结,如下
fllow1

DecorView的层级结构

DecorView作为我们的顶级View,一般内部包含了一个LinearLayout,在这个Layout中,又由两部分组成,顶部的TitleView和剩余部分的ContentView

如下图:
fllow2
读到这里,想必大家终于明白了为什么在Activity中,设置内容布局的时候调用的函数是setContentView了,对,我们设置的其实就是这个ContentView的内容。

关于MeasureSpace

什么是MeasureSpec?

MeasureSpec其实是一个32位的int值, 由两部分组成,高2位代表SpecMode低30位代表SpecSize. 为什么这样做而不干脆设置成两个值呢?因为这样可以减少变量个数,从而达到减少开销的目的。
MeasureSpec的主要作用是在onMeasure流程中对测量控件大小提供信息,具体的信息就是上面的,mode和size,最终来确定控件到底是如何测量的。

MeasureSpec的SpecMode的三种模式

上面提到了SpecMode, 有三类,分别是,
UNSPECIFIED
父容器不对View有任何尺寸上的限制,一般用于系统内部,表示一种测量状态

EXACTLY
此时View的大小就是SpecSize指定的值,对应的就是match_parent和具体数值这两种模式。

AT_MOST
View的大小不能大于SpecSize,对应就是wrap_content

MeasureSpec和LayoutParams的对应关系

MeasureSpec的生成是通过自身的LayoutParams和父容器的MeasureSpec共同决定的。

由于DecorView是顶级View,所以其生成MeasureSpec的过程与普通View略有不同,是根据屏幕的大小以及自身的layoutparams来决定的

对于普通的View,在获得其SpecMesure时,首先会根据父容器的MessureSpec来拆分获得,mode,size两个值, 再结合自身的layoutparams来决定自己的MeasureSpec中的Mode和Size两个属性的值,最后生成自己的MeasureSpec值。

具体的生成对应可以参考作者在书中给出的表格

如下图:
fllow3

至此,MeasureSpec就介绍完了,原本听起来高深莫测的东西,只要跟着这本书作者的思路一步步走下去,其实并不难懂。

u3coding

A software developer

Leave a Comment

Your email address will not be published. Required fields are marked *

*