1.MeasureSpc类说明
1.1 SDK 说明如下
A MeasureSpec encapsulates the layout requirements passed from parent to child. Each MeasureSpec represents a requirement for either the width or the height. A MeasureSpec is comprised of a size and a mode.即:MeasureSpc类封装了父View传递给子View的布局(layout)要求。每个MeasureSpc实例代表宽度或者高度(只能是其一)要求。
简单理解为一个32位的数字,其中前2位和后30位分别代表SpecMode和SpecSize
它有三种模式(SpecMode):
①最高两位是00的时候表示"未指定模式",即MeasureSpec.UNSPECIFIED。父元素部队自元素施加任何束缚,子元素可以得到任意想要的大小;一般用于系统内部,表示一种测量的状态。
②最高两位是01的时候表示"'精确模式",即MeasureSpec.EXACTLY。父元素已经检测出该元素的确切大小,View的最终大小就是SpecSize所对应的值;对应LayoutParams中的match_parent和具体数值两种模式。
③最高两位是11的时候表示"最大模式",即MeasureSpec.AT_MOST。父容器指定了一个可用大小即SpecSize,View的大小不能大于这个值;对应LayoutParams中的Wrap_content
常用的三个函数:
static int getMode(int measureSpec) : 根据提供的测量值(格式)提取模式(上述三个模式之一)
static int getSize(int measureSpec) : 根据提供的测量值(格式)提取大小值(这个大小也就是我们通常所说的大小)
static int makeMeasureSpec(int size,int mode) : 根据提供的大小值和模式创建一个测量值(格式)
1.2 MeasureSpc类源码分析
public class View implements ... {
...
public static class MeasureSpec {
private static final int MODE_SHIFT = 30; //移位位数为30
//int类型占32位,向右移位30位,该属性表示掩码值,用来与size和mode进行"&"运算,获取对应值。
private static final int MODE_MASK = 0x3 << MODE_SHIFT;
//向右移位30位,其值为00 + (30位0) , 即 0x0000(16进制表示)
public static final int UNSPECIFIED = 0 << MODE_SHIFT;
//向右移位30位,其值为01 + (30位0) , 即0x1000(16进制表示)
public static final int EXACTLY = 1 << MODE_SHIFT;
//向右移位30位,其值为02 + (30位0) , 即0x2000(16进制表示)
public static final int AT_MOST = 2 << MODE_SHIFT;
//创建一个整形值,其高两位代表mode类型,其余30位代表长或宽的实际值。可以是WRAP_CONTENT、MATCH_PARENT或具体大小exactly size
public static int makeMeasureSpec(int size, int mode) {
return size + mode;
}
//获取模式 ,与运算
public static int getMode(int measureSpec) {
return (measureSpec & MODE_MASK);
}
//获取长或宽的实际值 ,与运算
public static int getSize(int measureSpec) {
return (measureSpec & ~MODE_MASK);
}
}
...
}