对于普通的view,其测量在ViewGroup中的measureChildWithMargins函数中调用child view的measure开始测量。

1:从measure函数开始

     public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
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
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函数用来计算一个view的尺寸,其传入的参数为parentView对此view的宽/高限制信息。实际的尺寸测量将会调用onMeasure来完成,因此,子类必须重写onMeasure函数。

通过measure函数的源码我们也可以知道:首先,它是final的,所以不可以重写;其次,它主要是对传入的parentView的宽高限制信息进行了是否与上一次的相同的判断,若是相同则不调用onMeasure重新测量;

2:measure ——> onMeasure函数

     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}

通过其代码,我们可以知道主要用了这三个函数,我们一一分析:

2.1:getSuggestedMinimumWidth函数:返回android:minWidth和背景宽度二者之间的最大值

 protected int getSuggestedMinimumWidth() {
int suggestedMinWidth = mMinWidth; //mMinWidth对应android:minWidth属性所指定的值,如果它没有指定,那么默认为0 if (mBGDrawable != null) { //如果设置了背景
final int bgMinWidth = mBGDrawable.getMinimumWidth(); //背景的宽度,如果是ShapeDrawable那么为0,如果是BitmapDrawable则有原始宽高
if (suggestedMinWidth < bgMinWidth) { //如果设定的最小值小于背景图片宽度,那么设定最小值为背景图片宽度
suggestedMinWidth = bgMinWidth;
}
} return suggestedMinWidth;
}

2.2:getDefaultSize:如果measureSpec没有限定则返回size,否则返回measureSpec中的size

     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;
}

到此:我们可以总结getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec)的逻辑:如果parentView对尺寸没有限制(即parentView的模式为UNSPECIFIED),那么将返回view的suggested最小值,否则返回parentView指定的尺寸。getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec)类似。

2.3 setMeasuredDimension:很简单,设置测量的宽高(注意不是view实际的宽高,实际的宽高要等layout完成之后才确定,虽然几乎全部就是measure后的宽高)

     protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) {
mMeasuredWidth = measuredWidth;
mMeasuredHeight = measuredHeight; mPrivateFlags |= MEASURED_DIMENSION_SET;
}

至此,关于onMeasure函数分析结束。

===================================================================

http://www.cnblogs.com/willhua/

===================================================================

普通View的measure流程的更多相关文章

  1. Android View体系(七)从源码解析View的measure流程

    前言 在上一篇我们了解了Activity的构成后,开始了解一下View的工作流程,就是measure.layout和draw.measure用来测量View的宽高,layout用来确定View的位置, ...

  2. Android自定义View前传-View的三大流程-Measure

    Android自定义View前传-View的三大流程-Measure 参考 <Android开发艺术探索> https://developer.android.google.cn/refe ...

  3. Android自己定义view之measure、layout、draw三大流程

    自己定义view之measure.layout.draw三大流程 一个view要显示出来.须要经过測量.布局和绘制这三个过程,本章就这三个流程具体探讨一下.View的三大流程具体分析起来比較复杂,本文 ...

  4. 深入理解 Android 之 View 的绘制流程

    概述 本篇文章会从源码(基于Android 6.0)角度分析Android中View的绘制流程,侧重于对整体流程的分析,对一些难以理解的点加以重点阐述,目的是把View绘制的整个流程把握好,而对于特定 ...

  5. Android View的绘制流程

    写得太好了,本来还想自己写的,奈何肚里墨水有限,直接转吧.正所谓前人种树,后人乘凉.. View的绘制和事件处理是两个重要的主题,上一篇<图解 Android事件分发机制>已经把事件的分发 ...

  6. 自定义控件(视图)1期笔记02:View的绘制流程

    1. 引言: 来自源码的3个方法: (1)public final void measure():测量,用来控制控件的大小,final不建议覆写 (2)public void layout():布局, ...

  7. Android查缺补漏(View篇)--自定义 View 的基本流程

    View是Android很重要的一部分,常用的View有Button.TextView.EditView.ListView.GridView.各种layout等等,开发者通过对这些View的各种组合以 ...

  8. Android探究之View的绘制流程

    Android中Activity是作为应用程序的载体存在,代表着一个完整的用户界面,提供了一个窗口来绘制各种视图,当Activity启动时,我们会通过setContentView方法来设置一个内容视图 ...

  9. Android的自定义View及View的绘制流程

    目标:实现Android中的自定义View,为理清楚Android中的View绘制流程“铺路”. 想法很简单:从一个简单例子着手开始编写自定义View,对ViewGroup.View类中与绘制View ...

随机推荐

  1. 开源服务专题之-------rsync数据备份

    RSYNC是Remote Sync 远程同步的简称,与SCP的比较,SCP= 无法备份大量数据,类似windows的复制,而rsync=边复制 ,边统计,边比较,可以备份大量数据.可以镜像保存整个目录 ...

  2. 使用archiver在nodejs下打包

    archiver是一个在nodejs中能跨平台实现打包功能的模块,可以打zip和tar包,是一个比较好用的三方模块. 使用前先安装archiver模块. npm install archiver 建立 ...

  3. cdnjquery加载失败加载本地

    <script type="text/javascript" src="//libs.baidu.com/jquery/1.7.2/jquery.min.js&qu ...

  4. LINQ的Except方法

    在两个集合中,左边集合减去右边集合的元素: source code: List<int> a = new List<int>{ { }, { }, { } }; List< ...

  5. 在Excel中使用频率最高的函数的功能和使用方法

    在Excel中使用频率最高的函数的功能和使用方法,按字母排序: 1.ABS函数 函数名称:ABS 主要功能:求出相应数字的绝对值. 使用格式:ABS(number) 参数说明:number代表需要求绝 ...

  6. EL表达式错误attribute items does not accept any expressions

    解决方法是将 <%@taglib prefix="c" uri="http://java.sun.com/jstl/core"%> 改成 <% ...

  7. java之StringBuffer类详解

    StringBuffer 线程安全的可变字符序列. StringBuffer源码分析(JDK1.6): public final class StringBuffer extends Abstract ...

  8. Razor语法大全

    本文页面来源地址:http://www.cnblogs.com/dengxinglin/p/3352078.html Razor是基于framewor4以上写的一个开源项目:https://githu ...

  9. 1 UML基础

    学习设计模式的过程中,发现相关的作者们都会用UML类图来表示一个模式的整体脉络,这种方式确实直观明了,既能体现宏观思路.又能兼顾实现细节.真的是很妙的工具.在开始正式学习设计模式之前,有必要对UML有 ...

  10. 静态代码审查工具FxCop插件开发(c#)

    FxCop是一款微软官方提供的.net平台代码审查工具,目的是检查我们编写的程序集的代码是否符合规范.FxCop默认提供的是微软默认的审查规则,而且该规则符合<Framework DesignG ...