android中View.measure方法的源码注解
来源:互联网 发布:手机淘宝客户端是什么 编辑:程序博客网 时间:2024/04/28 13:15
首先来看measure方法的源码注解:
public final void measure(int widthMeasureSpec, int heightMeasureSpec) { //判断旧的mOldWidthMeasureSpec 是否与新的测量方式相同,只要有一个不同就要重新测量 //对widthMeasureSpec的理解: if ((mPrivateFlags & FORCE_LAYOUT) == FORCE_LAYOUT || widthMeasureSpec != mOldWidthMeasureSpec || heightMeasureSpec != mOldHeightMeasureSpec) { // first clears the measured dimension flag //清除标志位,"先取反,后与" :与是为了取被与的值 mPrivateFlags &= ~MEASURED_DIMENSION_SET; if (ViewDebug.TRACE_HIERARCHY) { ViewDebug.trace(this, ViewDebug.HierarchyTraceType.ON_MEASURE); } // measure ourselves, this should set the measured dimension flag back //开始测量 onMeasure(widthMeasureSpec, heightMeasureSpec); // flag not set, setMeasuredDimension() was not invoked, we raise // an exception to warn the developer //通过标志位判断是否执行了setMeasuredDimension()方法 if ((mPrivateFlags & MEASURED_DIMENSION_SET) != MEASURED_DIMENSION_SET) { throw new IllegalStateException("onMeasure() did not set the" + " measured dimension by calling" + " setMeasuredDimension()"); } mPrivateFlags |= LAYOUT_REQUIRED; } //将重新为旧的值赋值 mOldWidthMeasureSpec = widthMeasureSpec; mOldHeightMeasureSpec = heightMeasureSpec; }
measure函数有2个参数,widthMeasureSpec 和 heightMeasureSpec。
onMeasure(widthMeasureSpec, heightMeasureSpec)方法:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //执行setMeasuredDimension方法 //参数解释: setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec), getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec)); }
当我们重写onMeasure时,需要调用setMeasuredDimension来设置自身的mMeasuredWidth和mMeasuredHeight,否则,就会抛出上面那个异常
setMeasuredDimension方法:类似于执行setter方法
protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) { //将测量结果赋值 mMeasuredWidth = measuredWidth; mMeasuredHeight = measuredHeight; //添加flag,MEASURED_DIMENSION_SET mPrivateFlags |= MEASURED_DIMENSION_SET; }
计算都是在getDefaultSize函数里实现的:
//参数解析:size:大小//measureSpec:是一个复合的标志位public static int getDefaultSize(int size, int measureSpec) { //measureSpec是一个复合的概念:二进制表示:最前的2两位表示:mode;后30位表示尺寸 //关于mode:MeasureSpec.UNSPECIFIED这个是未执行大小:对应于wrap_content //MeasureSpec.AT_MOST:对应match_parent和fill_parent //MeasureSpec.EXACTLY:代表确切尺寸 int result = size; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); switch (specMode) { //未指定大小的情况下:返回建议的尺寸 case MeasureSpec.UNSPECIFIED: result = size; break; //AT_MOST,EXACTLY则返回按照mode测量的尺寸. case MeasureSpec.AT_MOST: case MeasureSpec.EXACTLY: result = specSize; break; } return result; }
关于getSuggestedMinimumHeight()
protected int getSuggestedMinimumHeight() { //判断是否有背景,没有的话返回mMinHeight 即控件的最小高度(通过属性获取的) //如果背景不为空,则返回mMinHeight 或mBackground.getMinimumHeight() return (mBackground == null) ? mMinHeight : max(mMinHeight, mBackground.getMinimumHeight()); }
public static class MeasureSpec { //设置mode的移位数 private static final int MODE_SHIFT = 30; private static final int MODE_MASK = 0x3 << MODE_SHIFT; //UNSPECIFIED为32个0 public static final int UNSPECIFIED = 0 << MODE_SHIFT; //EXACTLY为:01+30个0 public static final int EXACTLY = 1 << MODE_SHIFT; //AT_MOST为:10+30个0 public static final int AT_MOST = 2 << MODE_SHIFT; public static int makeMeasureSpec(int size, int mode) { //组建复合的measureSpec return size + mode; } public static int getMode(int measureSpec) { //取出mode return (measureSpec & MODE_MASK); } public static int getSize(int measureSpec) { //去除mode,获取size return (measureSpec & ~MODE_MASK); } }
测量总结:
measure(MeasureSpec.UNSPECIFIED,MeasureSpec.UNSPECIFIED)即measure(0,0)返回getSuggestedMinimumWidth()
如果采用MeasureSpec.AT_MOST或者
则舍弃getSuggestedMinimumWidth()得到的尺寸,返回int specSize =MeasureSpec.getSize(measureSpec);的值MeasureSpec.EXACTLY;这是传入measure()的measureSpec参数,是mode+size,因此采用此两种测量方式需要制定尺寸.
1 0
- android中View.measure方法的源码注解
- 源码解析Android中View的measure量算过程
- 源码解析Android中View的measure量算过程
- 源码解析Android中View的measure量算过程
- 源码解析Android中View的measure量算过程
- 【Android源码学习】View的measure流程
- android中View.measure方法详解
- android中View.measure方法详解
- android中View.measure方法详解
- android中View.measure方法详解
- android中View.measure方法详解
- View 的 measure 方法
- view 的 measure方法
- Android View的Measure
- android View measure过程源码解析
- Android中View的MeasureSpec以及Measure的过程
- 带着问题学习Android中View的measure测量
- Android中View的绘制原理之measure
- 数字功放
- Play 2.0 用户指南 - 使用JSON库
- str_split与explode
- kphp框架分享之html5中Video对象的preload、src和played属性讲解
- 深度学习 vs. 概率图模型 vs. 逻辑学
- android中View.measure方法的源码注解
- android下拉菜单 spinner 学习
- Java 中的堆和对象的区别
- PHP基础--字符串操作和运算符
- 探究CRC32算法实现原理-why table-driven implemention
- 转换加密工具类-MD5
- Spring编程式事务管理和声明式事务管理
- storyboard开发指南(1)简介
- 【Solutions系列】洪水应急地图