View的工作流程-对MeasureSpec认识

MeasureSpec:

MeasureSpec代表一个32位的int值,高2位代表SpecMode,低30位代表SpecSize,在很大程度决定一个View的规格。

  • 其中SpecMode是指测量模式,SpecSize是指某种测量模式下的规格大小。
  • SpecMode和SpecSize也是int值,它们可以打包为MeasureSpec
 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);
            }
        }
  • MeasureSpec可以解包为它们:
 @MeasureSpecMode
        public static int getMode(int measureSpec) {
            //noinspection ResourceType
            return (measureSpec & MODE_MASK);
        }

         public static int getSize(int measureSpec) {
            return (measureSpec & ~MODE_MASK);
        }

SpecMode有三个类型:

  • UNSPECIFIED:父容器不对View有任何限制,一般用于系统内部。
  • EXACTLY:父容器已经检测出View所需要的精确大小。它对应于LayoutParams中的match_parent和具体的数值这两种模式。
  • AT_MOST:父容器制定一个大小,View的大小不能大于这个值,它对应于wrap_content。

    LayoutParams和父容器一起决定View的MeasureSpec:

    这里主要是LayoutParams与MeasureSpec的关系:
    通过查看ViewGroup的measureChildWithMargin方法和getChildMeasureSpec可知:

  • 根据父容器的MeasureSpec同时结合View本身的LayoutParams来确定子元素的MeasureSpec
  • 子元素的可用大小为父容器的尺寸减去padding

    普通View的MeasureSpec的创建规则

    (不包括UNSPECIFIED)

  • 如果View采用的是固定宽高(dp/dx),则无论父容器的MeasureSpec是什么,View的MeasureSpec都会是精确模式。
  • 如果View的宽高为match_parent,(1)如果父容器为精准模式(EXACTLY),那么view的大小是精准模式且其大小为父容器的剩余空间;(2)如果父容器为最大模式(AT_MOST),,那么view的大小是最大模式且其大小不会超过父容器的剩余空间
  • 如果View的宽高为wrap_content,则无论父容器是精准模式还是最大模式,它都是最大模式且大小不会超过父容器的剩余空间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值