Android MeasureSpec的理解和源码的解析

Android MeasureSpec的理解和源码的解析.

MeasureSpec

MeasureSpec的创建规则:

 

关于MeasureSpec的理解

(1) MeasureSpec基础知识

MeasureSpec通常翻译为"测量规格",它是一个32位的int数据.其中高2位代表SpecMode即某种测量模式,低30位为SpecSize代表在该模式下的规格大小.可以通过:

               int specMode = MeasureSpec.getMode(measureSpec) 获取specMode
               int specSize = MeasureSpec.getSize(measureSpec) 获取SpecSize

常用的SpecMode有三种:

MeasureSpec.EXACTLY

官方文档:Measure specification mode: The parent has determined an exact size for the child. The child is going to be given those bounds regardless of how big it wants to be.

父容器已经检测出子View所需要的精确大小.该子View最终的测量大小即为SpecSize.

(1) 当子View的LayoutParams的宽(高)采用具体的值(如100px)时且父容器的MeasureSpec为 MeasureSpec.EXACTLY或者.MeasureSpec.AT_MOST或者MeasureSpec.UNSPECIFIED时:系统返回给该子View的specMode就为MeasureSpec.EXACTLY.系统返回给该子View的specSize就为子View自己指定的大小(childSize)

  通俗地理解:
  子View的LayoutParams的宽(高)采用具体的值(如100px)时,那么说明该子View的大小是非常明确的,明确到已经用具体px值指定的地步了.那么此时不管父容器的specMode是什么,系统返回给该子View的specMode总是MeasureSpec.EXACTLY,并且系统返回给该子View的specSize就为子View自己指定的大小(childSize).

(2) 当子View的LayoutParams的宽(高)采用match_parent时并且父容器的MeasureSpec为 MeasureSpec.EXACTLY时:
    系统返回给该子View的specMode就为 MeasureSpec.EXACTLY
    系统返回给该子View的specSize就为该父容器剩余空间的大小(parentLeftSize)
    通俗地理解:
    子View的LayoutParams的宽(高)采用match_parent时并且父容器的MeasureSpec为 MeasureSpec.EXACTLY.这时候说明子View的大小还是挺明确的:就是要和父容器一样大,更加直白地说就是父容器要怎样子View就要怎样.所以,如果父容器MeasureSpec为 MeasureSpec.EXACTLY那么:系统返回给该子View的specMode就为 MeasureSpec.EXACTLY,和父容器一样.
系统返回给该子View的specSize就为该父容器剩余空间的大小(parentLeftSize),就是父容器的剩余大小.同样的道理如果此时,MeasureSpec为 MeasureSpec.AT_MOST呢?系统返回给该子View的specMode也为 MeasureSpec.AT_MOST,和父容器一样.
 系统返回给该子View的specSize也为该父容器剩余空间的大小(parentLeftSize),就是父容器的剩余大小.

MeasureSpec.AT_MOST
 官方文档  The child can be as large as it wants up to the specified size.
 父容器指定了一个可用大小即specSize,子View的大小不能超过该值.
 (1) 当子View的LayoutParams的宽(高)采用match_parent时并且父容器的MeasureSpec为 MeasureSpec.AT_MOST时:
      系统返回给该子View的specMode就为 MeasureSpec.AT_MOST
      系统返回给该子View的specSize就为该父容器剩余空间的大小(parentLeftSize)
      这种情况已经在上面介绍 MeasureSpec.EXACTLY时已经讨论过了.
 (2) 当子View的LayoutParams的宽(高)采用wrap_content时并且父容器的MeasureSpec为 MeasureSpec.EXACTLY时:
      系统返回给该子View的specMode就为 MeasureSpec.AT_MOST
      系统返回给该子View的specSize就为该父容器剩余空间的大小(parentLeftSize)
      通俗地理解:    

      子View的LayoutParams的宽(高)采用wrap_content时说明这个子View的宽高不明确,要视content而定.
    这个时候如果父容器的MeasureSpec为 MeasureSpec.EXACTLY即父容器是一个精确模式;这个时候简单地说
      子View是不确定的,父容器是确定的,那么
       系统返回给该子View的specMode也就是不确定的即为 MeasureSpec.AT_MOST
      系统返回给该子View的specSize就为该父容器剩余空间的大小(parentLeftSize)
 (3) 当子View的LayoutParams的宽(高)采用wrap_content时并且父容器的MeasureSpec为 MeasureSpec.AT_MOST时:
       系统返回给该子View的specMode就为 MeasureSpec.AT_MOST
       系统返回给该子View的specSize就为该父容器剩余空间的大小(parentLeftSize)
       通俗地理解:  

      子View的LayoutParams的宽(高)采用wrap_content时说明这个子View的宽高不明确,要视content而定.
      这个时候如果父容器的MeasureSpec为 MeasureSpec.AT_MOST这个时候简单地说
    子View是不确定的,父容器也是不确定的,那么系统返回给该子View的specMode也就是不确定的即为 MeasureSpec.AT_MOST
 系统返回给该子View的specSize就为该父容器剩余空间的大小(parentLeftSize)
 MeasureSpec.UNSPECIFIED
 官方文档  The parent has not imposed any constraint on the child. It can be whatever size it wants.
 父容器不对子View的大小做限制.    一般用作Android系统内部,或者ListView和ScrollView.在此不做讨论.
 关于这个三种测量规格下面的源码分析中体现得很明显,也可参考以下附图.
 (2) 在onMeasure()时子View的MeasureSpec的形成过程分析关于该技术点的讨论,请看下面的源码分析.


    

 

 

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值