参考https://www.2cto.com/kf/201607/522371.html
是子控件的宽高最终究竟怎么样被确定?
你还记得我们之前自作聪明的根据测试结果进行推断计算公式吗?实际上子控件的宽高最终的决定方式很简单:
1、那些满足widthMode == MeasureSpec.EXACTLY && lp.width == 0 && lp.weight > 0的控件,在第一次测量过程中可以视为并没有被真正测量宽高。
2、对于明确指定了宽、高的值的控件,在第一次测量过程中也会先进行一次测量,这个时候测量的值就是我们明确指定的值。
3、在第一次测量过程之后,第二次测量过程开始之前,会计算得到一个layout的现有内容占据的宽度mTotalLength,这个宽度是:所有子控件的左、右(上、下)外边距 + 被明确赋值的控件的宽、高 + layout的内边距。
4、对于weight的计算,如果控件的宽高设置的是0,它们所分配到的实际的范围其实是变量share的值,即”子控件的weight * layout剩余的空间 / weightSum;如果不为0,则是share+明确设定的宽、高值”。
这个时候,我们再以“layout宽为1080px,weightSum为1,button的width为100px,weight为0.5”来说,
其实我们就不用再去套什么所谓的公式了,通过源码的理解,我们能够轻松描述它的计算过程。
因为明确的设置了width为100px,所以在第一次测量过程中,button就被设置为了100px。
当第一次测量完成,得到的mTotalLength实际上也就是100px,因为我们的layout里就只有一个button,
并且button并没有设置外边距(margin),layout也没有设置内边距(padding)。
所以这个时候对于进行第二次测量过程,delta计算后得到的值实际上是:1080px - 100px = 980px。
而share的计算则是:0.5 * 980px / 1 = 490px;而因为该button明确指定了不为0的width值,所以其最终的实际宽度是:
share + button.getMeasureWidth = 490 + 100 =590px。