View 的测量 MeasureSpec

我们平常自定义都是重写 view 的 onMeasure(int widthMeasureSpec, int heightMeasureSpec)方法,而这个方法传入的宽和高都是一个32位 int 值。下面我们揭开这层神秘的面纱。

MeasureSpec 解析

MeasureSpec 是位于 View 类中的一个静态类,也就 100 行左右。我们先来看其中的变量。

   public static class MeasureSpec {private static final int MODE_SHIFT = 30;private static final int MODE_MASK  = 0x3 << MODE_SHIFT;/*** 测量指定模式:父容器不对子 view 施加任何约束,它可以是它想要的任何尺寸。* 一般系统中使用* 二进制值为:00000000000000000000000000000000*/public static final int UNSPECIFIED = 0 << MODE_SHIFT;/*** 测量规范模式:父容器确定子 view 的大小* 相当于子 view 的match_parent* 二进制值为:01000000000000000000000000000000*/public static final int EXACTLY     = 1 << MODE_SHIFT;/*** 测量规范模式:父容器指定一个可用大小,子 view 的大小不能超过这个值。* 相当于子 view 的 wrap_content* 二进制值为:10000000000000000000000000000000*/public static final int AT_MOST     = 2 << MODE_SHIFT;}

这三种模式都是通过对 MODE_SHIFT 进行左移得到的值,其二进制相应的值已经在注释中说明。所以说

View 的 MeasureSpec = SpecMode 模式(前两位) + SpecSize 尺寸(后30位)

MeasureSpec 方法

MeasureSpec 对外提供了一些静态方法,进行大小的打包和获取。

   public static class MeasureSpec {/*** 将 size 大小和 mode 模式打包,生成一个 int 值*/public static int makeMeasureSpec(int size,nt mode) {if (sUseBrokenMakeMeasureSpec) {return size + mode;} else {return (size & ~MODE_MASK) | (mode & MODE_MASK);}}/*** 获取 MeasureSpec 中的模式*/@MeasureSpecModepublic static int getMode(int measureSpec) {//noinspection ResourceTypereturn (measureSpec & MODE_MASK);}/*** 获取 MeasureSpec 中的尺寸*/public static int getSize(int measureSpec) {return (measureSpec & ~MODE_MASK);}}

父 View如何通过 MeasureSpec 控制子 View 大小

在 ViewGroup 中有一个 measureChild方法。可以看出,子 view 的 MeasureSpec 是通过父容器的 MeasureSpec 和子 view 的 LayoutParams所决定。最终会调用子 view 的 onMeasure方法。

protected void measureChild(View child, int parentWidthMeasureSpec,int parentHeightMeasureSpec) {final LayoutParams lp = child.getLayoutParams();final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,mPaddingLeft + mPaddingRight, lp.width);final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,mPaddingTop + mPaddingBottom, lp.height);child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}

MeasureSpec 和子 view 的 LayoutParams 对应关系如下图

子 View 的测量

至此,我们开始说的 onMeasure()方法的两个参数来源都已经清楚了,再来看 View 中的 onMeasure()执行了哪些操作。

 /*** 测量子 view 大小*/protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));}/*** 返回一个建议值*/protected int getSuggestedMinimumWidth() {return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());}/*** 根据建议大小和measureSpec返回默认大小*/public static int getDefaultSize(int size, int measureSpec) {int result = size;int specMode = MeasureSpec.getMode(measureSpec);int specSize = MeasureSpec.getSize(measureSpec);switch (specMode) {case MeasureSpec.UNSPECIFIED:result = size;break;case MeasureSpec.AT_MOST:case MeasureSpec.EXACTLY:result = specSize;break;}return result;}

View 的测量 MeasureSpec相关推荐

  1. 快速理解android View的测量onMeasure()与MeasureSpec

    笔者之前有一篇文章已经使用onMeasure()解决了listview与scollview的显示冲突问题,博客地址如下: onMeasure简单方法 完美解决ListView与ScollView冲突问 ...

  2. 自定义View:测量measure,布局layout,绘制draw

    1. 什么是View 在Android的官方文档中是这样描述的:表示了用户界面的基本构建模块.一个View占用了屏幕上的一个矩形区域并且负责界面绘制和事件处理. 手机屏幕上所有看得见摸得着的都是Vie ...

  3. View的三大流程之View的测量

    1. public class View extends Object implements Drawable.Callback KeyEvent.Callback AccessibilityEven ...

  4. View的测量规则以及三大方法流程

    通过前面几篇的深入分析,相信大家对View的理解已经很深了,我们说了setContentView背后做了什么,说了View从xml加载到通过WindowManager添加View后的一系列操作,说了A ...

  5. 长谈:关于 View Measure 测量机制,让我一次把话说完

    <倚天屠龙记中>有这么一处:张三丰示范自创的太极剑演示给张无忌看,然后问他记住招式没有.张无忌说记住了一半.张三丰又慢吞吞使了一遍,问他记住多少,张无忌说只记得几招了.张三丰最后又示范了一 ...

  6. 自定义View之测量onMeasure 一

    1 View默认的onMeasure实现 自定义View(ViewGroup)重要的三个步骤:测量,布局(只在ViewGroup中),绘制,在Android绘图的专题中已经对绘制进行了讲解,今天主要学 ...

  7. 如何使用Gerber View 软件测量孔径?

    近期有很多小伙伴在咨询关于孔径的事,问:"在 CAM350 中可以测量孔径,在望友 Gerber View 怎么测量?".今天就为大家介绍一下在望友 Gerber View 软件中 ...

  8. android群英传 自定义滑动view,《Android群英传》读书笔记

    <Android群英传>作者:徐宜生 本身感觉自己在动画这一块,缺的东西太多,在知乎上看到大家都推荐这一本书. 所以在kindle上看了样章,觉得非常值得入手,而且不仅仅是动画,是一本难得 ...

  9. Android GUI之View测量

    在上篇文章(http://www.cnblogs.com/jerehedu/p/4607599.html#gui)中,根据源码探索了View的绘制过程,过程有三个主要步骤,分别为测量.布局.绘制.系统 ...

  10. Android自定义View:MeasureSpec的真正意义与View大小控制

    自定义View是Android开发中最普通的需求,灵活控制View的尺寸是开发者面临的第一个问题,比如,为什么明明使用的是WRAP_CONTENT却跟MATCH_PARENT表现相同.在处理View尺 ...

最新文章

  1. Ubuntu 12.04安装Sun JDK 6
  2. 小记 | 从 0 到 1,看我玩弄千万日志于股掌
  3. 最快让你上手ReactiveCocoa之进阶篇
  4. 手把手教你搭建Hadoop生态系统伪分布式集群
  5. Linux学习之CentOS(二十九)--Linux网卡高级命令、IP别名及多网卡绑定
  6. WPF企业内训全程实录(下)
  7. 100元左右的鼠标推荐
  8. MySQL笔记——JDBC入门
  9. php session 封装类,PHP封装的数据库保存session功能类
  10. 云计算(1)---基础知识
  11. 前端职业规划 - 前端技术专家们的生死书
  12. Ubuntu学习(应用集合、命令行以及遇到的问题)
  13. 凸优化第五章对偶 5.3 几何解释
  14. 构建REST风格的Web Service (转)
  15. MySQL查询所有叶子节点
  16. 空间频率(lp/mm,cycles/mm,lp/mrad,cycles/mrad)
  17. Android使用Socket.IO实现即时通讯
  18. 珞石(ROKAE)机械手简单的编程
  19. shift delete删除的文件怎么恢复,神操作只用一招
  20. brpc介绍、编译与使用

热门文章

  1. 微信小程序“淘淘猜成语”开发教程(该成语接龙已上线,功能齐全)
  2. 大众点评美食评论爬虫
  3. .NET 配置系统未能初始化”异常
  4. ssm心理咨询服务平台毕业设计源码324615
  5. html5 canvas实现led样式数字字体
  6. 《惢客创业日记》2019.05.07(周二)永远匿名的红颜知己(四)
  7. 【面试招聘】我的秋招记录——(自然语言处理-面经+感悟)
  8. 问题 C: [入门OJ]和||
  9. Copula、CoVaR、Garch、DCC、藤Vine、BEKK、SV、ECM
  10. web前端顶岗实习总结报告_web前端年度工作总结范文