MeasureSpec有以下三种模式:
public static final int UNSPECIFIED = 0 << MODE_SHIFT;
public static final int EXACTLY = 1 << MODE_SHIFT;
public static final int AT_MOST = 2 << MODE_SHIFT;
分别表示:
- 精确模式(MeasureSpec.EXACTLY)
在这种模式下,尺寸的值是多少,那么这个组件的长或宽就是多少。 - 最大模式(MeasureSpec.AT_MOST)
这个也就是父组件,能够给出的最大的空间,当前组件的长或宽最大只能为这么大,当然也可以比这个小。 - 未指定模式(MeasureSpec.UNSPECIFIED)
这个就是说,当前组件,可以随便用空间,不受限制。
我们在MeasureSpec这个类中可以看到: private static final int MODE_SHIFT = 30; private static final int MODE_MASK = 0x3 << MODE_SHIFT;
其中MODE_MASK就是0x3(16进制的3)等同于10进制的3,转化为二进制就是 00000000 00000000 00000000 00000011 。右移30位变成二进制 11000000 00000000 00000000 00000000。
下面我们重点看看如下这个方法:
public static int makeMeasureSpec(@IntRange(from = 0, to = (1 << MeasureSpec.MODE_SHIFT) - 1) int size,@MeasureSpecMode int mode) {
if (sUseBrokenMakeMeasureSpec) {
return size + mode;
} else {
return (size & ~MODE_MASK) | (mode & MODE_MASK);
}
}
默认sUseBrokenMakeMeasureSpec = false;
我们时常重写ListView的方法如下:
public class MyListView extends ListView {
public MyListView(Context context) {
super(context);
}
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec
,MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE>>2,MeasureSpec.AT_MOST));
}
}
Integer.MAX_VALUE的二进制值为 11111111 11111111 11111111 11111111 ,>>2,二进制值变更为 00111111 11111111 11111111 11111111。
(size & ~MODE_MASK) | (mode & MODE_MASK);
~MODE_MASK 11000000 00000000 00000000 00000000
(size & ~MODE_MASK) 11111111 11111111 11111111 11111111
(mode & MODE_MASK) 11000000 00000000 00000000 00000000
所以返回值为 11111111 11111111 11111111 11111111 前面两位代表MODE。