View的工作流程主要是指measure、layout、draw这三大流程。
- measure,测量,是一个确定元素宽高的过程。
- layout,布局,是一个确定元素位置的过程。
- draw,绘制,是把元素画到屏幕上的过程。
说到measure就不得不说MeasureSpec。它是一个32位的int值,其中,高2位代表SpecMode,低30位代表SpecSize。SpecMode指测量模式,SpecSize就是在某种测量模式下得到的大小。
SpecMode有三类,常用的是其中两类:
- EXACTLY,“确切的”,表示通过综合parent和child的情况,child的大小已经可以确定了
- AT_MOST,“最多能给多少”,表示虽然现在parent还没办法确认child的大小,但,parent会告诉child他最多能提供多少空间,然后child自行决定size,但无论如何child的size都不应该超过parent能提供的最大值。
在很多文章中会看到这样解释:EXACTLY对应match_parent和具体数值,AT_MOST对应wrap_content。这种说法不能算错,但并没有触及到SpecMode的本质,不利于读者理解。
从宏观上来说,measure就是一个遍历的过程。尤其是当在一开始parent不能确定自己size的时候,它就需要把每一个child的size测量好,再求和,这样才能知道自己会被“撑”多大。
从菊部来说,measure是一个parent与child相互协商的过程。
以测量child的height为例,大致分为这么几种情况:
- child的height是一个具体数值,例如,100dp。
此时,无论parent的剩余空间够不够,child最后的高度都会是100dp。大不了,child显示不完全。 - child的height是match_parent,表示child想把parent的剩余空间全部占为己有
如果此时parent已经可以确定剩余空间大小,那child的大小也就可以确定了,so,传给child的MeasureSpec会是 “EXACTLY+剩余空间”。
如果此时parent还未能确定剩余空间大小,传给child的MeasureSpec就是“AT_MOST+剩余空间”。 - child的height是wrap_content,表示child想自行决定高度
不管parent剩余空间能否确定,传给child的都是“AT_MOST+剩余空间”
“EXACTLY+剩余空间”,意思是,按照之前咱商量好的空间计算规则,child应该就是这么大。
“AT_MOST+剩余空间”,意思是,我能给你的最多就是这样了,你最好别越界。
所以MeasureSpec到底是什么呢?
MeasureSpec是综合了“parent的现状”和“child对空间的要求”之后的产物,是parent对child的在空间占用方面的建议。之所以说是“建议”,因为它并不具有强制性,最后决定自己size的还是child的onMeasure方法。
网友评论