MeasureSpec字面意思为测量的规格,他决定了view的测量过程
接下来探讨几个问题来学习MeauseSpec
1. MeasureSpec的构成
2. 如何创建MeasureSpec
3. 默认View的OnMeasure过程中对MeasureSpec的处理
一.MeasureSpec的构成
MeasureSpec代表一个32位的int值,前俩位代表SpecMode,后30位代表SpecSize.其中:SpecMode代表测量的模式,SpecSize值在某种测量模式下的规格大小。
共有三种测量模式:
1. EXACTLY: 父容器已经检测出子View所需要的精确大小,这个时候view的大小即为SpecSize的大小,他对应于布局参数中的MATCH_PARENT,或者精确大小值
2.AT_MOST: 父容器指定了一个大小,即SpecSize,子view的大小不能超过这个SpecSize的大小
3.UNSPECIFIED: 表示子View想多大都可以
二.如何创建MeasureSpec
MeasureSpec内部提供了创建MeasureSpec的方法:
public static int makeMeasureSpec(int size, int mode) {
if (sUseBrokenMakeMeasureSpec) {
return size + mode;
} else {
return (size & ~MODE_MASK) | (mode & MODE_MASK);
}
}
MeasureSpec代表一个32位的int值,前俩位代表SpecMode,后30位代表SpecSize.通过巧妙的位运算,即可通过MeasureSpec来得到SpecSize,SpecMode.
public static int getMode(int measureSpec) {
return (measureSpec & MODE_MASK);
}
public static int getSize(int measureSpec) {
return (measureSpec & ~MODE_MASK);
}
系统内部是通过MeasureSpec来对view进行测量。在view测量的时候,系统会将LayoutParams在父容器的约束下创建MeasureSpec.
view的顶级View为DecorView.他的MeasureSpec有窗口的尺寸与布局参数来决定。对于普通的View,他的MesureSpec由父容器的MeasureSpec与自身的布局参数来一起决定的。
DecorView的MeasureSpec创建过程如下: