MeasureSpec
MODE_SHIFT = 30;
MODE_MASK = 0x3 << MODE_SHIFT;
UNSPECIFIED = 0 << MODE_SHIFT;
EXACTLY = 1 << MODE_SHIFT;
AT_MOST = 2 << MODE_SHIFT;
上面做的其实是位运算,我们转成2进制看吧
<<运算规则: 按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零。
MODE_SHIFT = 30 移动的位数。
MODE_MASK = 0x3 << MODE_SHIFT 把0x3向左移动30个位数。
0x3 = 0000 0000 0000 0000 0000 0000 0000 0011 左移30位等于 11 00 0000 0000 0000 0000 0000 0000 0000 。
UNSPECIFIED = 0 << MODE_SHIFT = 0000 0000 0000 0000 0000 0000 0000 0000 = 0
EXACTLY = 1 << MODE_SHIFT = 01 00 0000 0000 0000 0000 0000 0000 0000 = 1073741824
AT_MOST = 2 << MODE_SHIFT = 1 000 0000 0000 0000 0000 0000 0000 0000 =-2147483647
假设 widthMeasureSpec=measureSpec =1073742678 (这是我debug出来的值)=01 00 0000 0000 0000 0000 0011 01 01 011 0
MeasureSpec.getSize(widthMeasureSpec) = 854 = 0011 01 01 011 0
看具体getSize里面是怎么实现的: return (measureSpec & ~MODE_MASK);
~MODE_MASK = ~11 00 0000 0000 0000 0000 0000 0000 0000 =00 11 1111 1111 1111 1111 1111 1111 1111
measureSpec & ~MODE_MASK = 1073742678 &00 11 1111 1111 1111 1111 1111 1111 1111 = 01 00 0000 0000 0000 0000 0011 01 01 011 0 & 00 11 1111 1111 1111 1111 1111 1111 1111 =0000 0000 0000 0000 0000 0011 0101 0110 = 854
& :两个都为1时结果为1。
MeasureSpec.getMode(widthMeasureSpec) = 1073741824=01 00 0000 0000 0000 0000 0000 0000 0000
measureSpec & MODE_MASK = 1073742678 & 11 00 0000 0000 0000 0000 0000 0000 0000 = 01 00 0000 0000 0000 0000 0011 01 01 011 0 & 11 00 0000 0000 0000 0000 0000 0000 0000 =0100 0000 0000 0000 0000 0000 0000 0000 = 1073741824 = EXACTLY
从上面的分析可以看出widthMeasureSpec 里面存储的是两个内容一个是类型mode一个是值width,系统是通过把两个值相加用一个值表示两个内容 makeMeasureSpec(int size, int mode) {return size + mode;} 这个函数就是用来做相加操作的,也就是把type和value打包成一个值,总结:高位用于存储类型,低位用于存储具体值。
另外 上面的是当宽度设置为fill_parent的时候。
当宽度设置为wrap_content的时候 widthMeasureSpec=-2147482794 = 1111 1111 1111 1111 1111 1100 1010 1010
mode = -2147483648 = Integer.MIN_VALUE= 1000 0000 0000 0000 0000 0000 0000 0000 = AT_MOST
width = 854