View 的测量 MeasureSpec
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相关推荐
- 快速理解android View的测量onMeasure()与MeasureSpec
笔者之前有一篇文章已经使用onMeasure()解决了listview与scollview的显示冲突问题,博客地址如下: onMeasure简单方法 完美解决ListView与ScollView冲突问 ...
- 自定义View:测量measure,布局layout,绘制draw
1. 什么是View 在Android的官方文档中是这样描述的:表示了用户界面的基本构建模块.一个View占用了屏幕上的一个矩形区域并且负责界面绘制和事件处理. 手机屏幕上所有看得见摸得着的都是Vie ...
- View的三大流程之View的测量
1. public class View extends Object implements Drawable.Callback KeyEvent.Callback AccessibilityEven ...
- View的测量规则以及三大方法流程
通过前面几篇的深入分析,相信大家对View的理解已经很深了,我们说了setContentView背后做了什么,说了View从xml加载到通过WindowManager添加View后的一系列操作,说了A ...
- 长谈:关于 View Measure 测量机制,让我一次把话说完
<倚天屠龙记中>有这么一处:张三丰示范自创的太极剑演示给张无忌看,然后问他记住招式没有.张无忌说记住了一半.张三丰又慢吞吞使了一遍,问他记住多少,张无忌说只记得几招了.张三丰最后又示范了一 ...
- 自定义View之测量onMeasure 一
1 View默认的onMeasure实现 自定义View(ViewGroup)重要的三个步骤:测量,布局(只在ViewGroup中),绘制,在Android绘图的专题中已经对绘制进行了讲解,今天主要学 ...
- 如何使用Gerber View 软件测量孔径?
近期有很多小伙伴在咨询关于孔径的事,问:"在 CAM350 中可以测量孔径,在望友 Gerber View 怎么测量?".今天就为大家介绍一下在望友 Gerber View 软件中 ...
- android群英传 自定义滑动view,《Android群英传》读书笔记
<Android群英传>作者:徐宜生 本身感觉自己在动画这一块,缺的东西太多,在知乎上看到大家都推荐这一本书. 所以在kindle上看了样章,觉得非常值得入手,而且不仅仅是动画,是一本难得 ...
- Android GUI之View测量
在上篇文章(http://www.cnblogs.com/jerehedu/p/4607599.html#gui)中,根据源码探索了View的绘制过程,过程有三个主要步骤,分别为测量.布局.绘制.系统 ...
- Android自定义View:MeasureSpec的真正意义与View大小控制
自定义View是Android开发中最普通的需求,灵活控制View的尺寸是开发者面临的第一个问题,比如,为什么明明使用的是WRAP_CONTENT却跟MATCH_PARENT表现相同.在处理View尺 ...
最新文章
- Ubuntu 12.04安装Sun JDK 6
- 小记 | 从 0 到 1,看我玩弄千万日志于股掌
- 最快让你上手ReactiveCocoa之进阶篇
- 手把手教你搭建Hadoop生态系统伪分布式集群
- Linux学习之CentOS(二十九)--Linux网卡高级命令、IP别名及多网卡绑定
- WPF企业内训全程实录(下)
- 100元左右的鼠标推荐
- MySQL笔记——JDBC入门
- php session 封装类,PHP封装的数据库保存session功能类
- 云计算(1)---基础知识
- 前端职业规划 - 前端技术专家们的生死书
- Ubuntu学习(应用集合、命令行以及遇到的问题)
- 凸优化第五章对偶 5.3 几何解释
- 构建REST风格的Web Service (转)
- MySQL查询所有叶子节点
- 空间频率(lp/mm,cycles/mm,lp/mrad,cycles/mrad)
- Android使用Socket.IO实现即时通讯
- 珞石(ROKAE)机械手简单的编程
- shift delete删除的文件怎么恢复,神操作只用一招
- brpc介绍、编译与使用
热门文章
- 微信小程序“淘淘猜成语”开发教程(该成语接龙已上线,功能齐全)
- 大众点评美食评论爬虫
- .NET 配置系统未能初始化”异常
- ssm心理咨询服务平台毕业设计源码324615
- html5 canvas实现led样式数字字体
- 《惢客创业日记》2019.05.07(周二)永远匿名的红颜知己(四)
- 【面试招聘】我的秋招记录——(自然语言处理-面经+感悟)
- 问题 C: [入门OJ]和||
- Copula、CoVaR、Garch、DCC、藤Vine、BEKK、SV、ECM
- web前端顶岗实习总结报告_web前端年度工作总结范文