View的绘制流程(二)--------view的measure过程

在分析view的measure过程之前,有必要看看什么是measureSpec,因为它在view的measure流程中经常出现,比较重要,不知道的童鞋可能会感觉这是啥玩意儿,好高大上阿。。。其实看过之后会发现measureSpec并不难,下面开始----

一、MeasureSpec简介

MeasureSpec代表一个32位的int值,这个从类的常量中就可以看出来,它是View的内部类,如下:

public static class MeasureSpec {
        private static final int MODE_SHIFT = 30;
        private static final int MODE_MASK  = 0x3 << MODE_SHIFT;

        /**
         * 父元素不限制子元素,子元素想要多大就多大
         */
        public static final int UNSPECIFIED = 0 << MODE_SHIFT;

        /**
         * 精确:子元素会被给予一个确定的值,对应LayoutParams中的Match_parent和具体的数值
         */
        public static final int EXACTLY     = 1 << MODE_SHIFT;

        /**
         * 不大于:父元素提供一个可用的值,子元素不能超过这个值,对应LayoutParams中的wrap_content
         */
        public static final int AT_MOST     = 2 << MODE_SHIFT;
  
        public static int makeMeasureSpec(int size, int mode) {
            if (sUseBrokenMakeMeasureSpec) {
                return size + mode;
            } else {
                return (size & ~MODE_MASK) | (mode & MODE_MASK);
            }
        }
        
        public static int getMode(int measureSpec) {
            return (measureSpec & MODE_MASK);
        }
         */
        public static int getSize(int measureSpec) {
            return (measureSpec & ~MODE_MASK);
        }
        . . .
        
}

MeasureSpec提供了三种模式(SpecMode),分别为上面的UNSPECIFIED、EXACTLY、AT_MOST

<<是位运算符,一般用于二进制,代表向左移位,MODE_SHIFT是个常量,30,所以UNSPECIFIED就是0向左移位30位,EXACTLY是1向左移位30位,AT_MOST是2向左移位30位,如下表示:

UNSPECIFIED:

移位前:00000000 00000000 00000000 00000000

移位后:00000000 00000000 00000000 00000000

EXACTLY:

        移位前:00000000 00000000 00000000 00000001

移位后:01000000 00000000 00000000 00000000

AT_MOST:

       移位前:00000000 00000000 00000000 00000010

       移位后:10000000 00000000 00000000 00000000

总的来说,其实就是MeasureSpec中,高两位代表SpecMode,低30位代表SpecSize。MeasureSpec类将SpecMode(模式)和SpecSize(大小)整合成一个int值,方法就是上面代码中的makeMesaureSpec方法,同时为了方便,也提供了方法可以从一个MeasureSpec值当中取出来原始的SpecMode和SpecSize,就是上面代码中的getMode和getSize,方法都很简单,这里可以简单解释下:

MODE_MASK是3向左移位30位,即11000000 00000000 0000000000000000,取反就是00111111 11111111 11111111 11111111。

把已整合的MeasureSpec值和MODE_MASK做&运算,即可得到SpecMode,将已整合的MeasureSpec值和取反后的MODE_MASK即可得到SpecSize。

另外,MeasureSpec和LayoutParams是有对应关系的,系统中是通过measureSpec来测量View的,但是在外部一般都是通过设置LayoutParams来改变View的,比如wrap_content和match_parent等。那么中间是怎么转换的呢,首先需要知道一点,就是View的MeasureSpec并不是唯一由LayoutParams来决定的,LayoutParams是需要和父容器一起才能决定view的MeasureSpec,在view测量的时候,系统会将LayoutParams在父容器的约束下转换成对应的MeasureSpec。

PS:顶级vi

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值