Android开发艺术探索笔记(14)- MeasureSpec

来源:互联网 发布:蛤蟆吃创建不了网络 编辑:程序博客网 时间:2024/05/22 00:23

MeasureSpec是自定义View是重写View的onMeasure的一个参数,利用这个参数我们可以准确测量View的宽高。

MeasureSpec有一个很有意思的思想,其实MeasureSpec类中有两个属性,但是Android并不像我们平常一样

private int mode;private int size;

而是采取一种合并的方式,将mode和size合并为一个32位的int值。高2位代表mode,低30位代表size,还提供了getSize和getMode两个方法获取。因为看源码晕晕的,所以特意复习了一下java的位移,这里记录一下。

// i为0000 0011 -> 3int i = 3;// i左移1位,b为0000 0110 -> 6int b = i << 1;// i右移1位,c为0000 0001 -> 1int c = i >> 1;// b | c,d为0000 0111 -> 7int d = b | c;// b & c,e为0000 0000 -> 0int e = b & c;// ~i,f为1111 1100int f = ~i;

上面的代码足够让我理解位移的知识点了。更深入的可以自行查找!!回到MeasureSpec,getMode有3中方式:

(1)UNSPECIFIED

不对View做任何的限制,只要用在系统的View,so i don`t care !!

(2)EXACTLY(精确模式)

View已经指定了精确的值,也是最终View的大小。对应LayoutParams中match_parent或具体的width。

(3)AT_MOST(最大模式)

View没有指定精确大小,取决于View的内容,刚好装够内容就行,但是不能超过父容器剩余大小。对应LayoutParams的wrap_content。

各种模式错综复杂,子View的大小还会受限制于父容器的大小,关系如表

作者也简单总结了一下:

当子View指定dp/px时,无论父容器是哪种模式,子View都是EXACTLY模式,而且大小都是子View指定的大小。

当子View指定match_parent时,受父容器影响。如果父容器也是EXACTLY模式,那么子View也是EXACTLY模式,而且大小是父容器剩余大小。如果父容器是AT_MOST模式,那么子View也是AT_MOST模式,大小最大也是父容器剩余大小。

当子View指定wrap_content时,无论父容器是哪种模式,子View都是AT_MOST模式,最大大小是父容器剩余大小。

所以View的测量大小,需要结合自身的LayoutParams和父容器的模式,也就是MeasureSpec。

0 0