View.measure(0,0)方法什么情况下能正确计算宽高

200 阅读2分钟

我们常常在代码看到view.measure(0,0)手动触发View的measure测量过程,然后再通过view.getMeasureWidth获取宽高,但是这种写法一定能获取正确吗?什么场景下获取不准确呢?

image.png

image.png

从日志可以看出,我们此时通过view.measure(0,0)直接传递0进去是可以正确获取测量宽高的,现在我们改下布局换成精确数值。

image.png

此时打印日志再看:

image.png

明显和我们最后通过post得出的宽高不一样。说明我们通过view.measure(0,0)是不能正确地获取到宽高的。

下面我们来分析下: View.measure(0,0)方法中的参数代表mode为MeasureSpec.UNSPECIFIED size为0,表达的意思是view自己来决定你的大小吧 当mode为MeasureSpec.AT_MOST,size为MeasureSpec.size。表达的意思是view自己来决定你的大小吧,但是最大值不能超过MeasureSpec.size。 当mode为MeasureSpec.EXACTLY,size为 MeasureSpec.size。表达的意思是: 你的大小为MeasureSpec.size。 所以当系统自行处理布局流程时,当是第一种情况时,使用measure(0,0)计算处理的结果是正确的,因为系统让子View自行计算自己大小和我们让它自行计算自己大小,计算结果一样的。 当是第二种情况时,使用measure(0,0)计算出来的值可能正确也可能不正确,因为系统让子View自行计算自己大小,但大小不能超过MeasureSpec.size,但我们光使用measure(0,0)时,measure(0,0)能正确计算,但View计算的大小大于MeasureSpec.size,measure(0,0)计算出来的大小值就不正确了。对应我代码中第一个例子。(绝大多数情况wrap_content时,measure(0,0)是正确的) 当是第三种情况时,measure(0,0)计算的值如果正好是我们代码中写的精确值那就是正确的(极少数情况)。

下面我们来到底怎么计算呢? 第一种情况:当是wrap_content时

image.png

image.png

其中1<<30-1代表View大小理论上支持的最大值。

第二种情况:当都是精确值 image.png

image.png

image.png 第三种情况match_parent 这种模式无法通过view.measure(0,0)测量,必须要知道(父类容器的剩余大小,此时我们不知道剩余大小是多少)