android中View.measure方法详解
来源:互联网 发布:java导出excel 换行符 编辑:程序博客网 时间:2024/04/28 18:38
View
源码路径 frameworks\base\core\java\android\view\View.java
源码中国链接:http://www.oschina.net/code/explore/android-2.2-froyo/android/view/View.java
- 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;
- }
(mPrivateFlags这个还没研究,先跳过了)
1.检查传入的widthMeasureSpec和heightMeasureSpec是否与当前的值是一样的,不一样的话,调用onMeasure函数,并设置mPrivateFlags。
2.保存新值到mOldWidthMeasureSpec和mOldHeightMeasureSpec。这两个变量不用深究了,没有其他地方用到,就只是在这个函数中用来比较值用的。
3.这里判断符合条件后会抛出一个IllegalStateException的异常,它的提示信息很清楚,告诉我们要调用setMeasuredDimension()方法。但到底是怎么回事呢?这是在你需要重写onMeasure函数时需要注意的。
先来看看默认的View的onMeasure函数吧:
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
- getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
- }
继续来看setMeasuredDimension:
- protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) {
- mMeasuredWidth = measuredWidth;
- mMeasuredHeight = measuredHeight;
- mPrivateFlags |= MEASURED_DIMENSION_SET;
- }
- 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;
- }
看到了一个MeasureSpec,看来主要工作是在这里,必须得进去看看了。
- public static class MeasureSpec {
- private static final int MODE_SHIFT = 30;
- private static final int MODE_MASK = 0x3 << MODE_SHIFT;
- public static final int UNSPECIFIED = 0 << MODE_SHIFT;
- public static final int EXACTLY = 1 << MODE_SHIFT;
- public static final int AT_MOST = 2 << MODE_SHIFT;
- public static int makeMeasureSpec(int size, int mode) {
- return size + mode;
- }
- public static int getMode(int measureSpec) {
- return (measureSpec & MODE_MASK);
- }
- public static int getSize(int measureSpec) {
- return (measureSpec & ~MODE_MASK);
- }
- }
类不大,就都贴出来了,为了精简篇幅,去掉了注释和toString函数。
这里MODE_MASK二进制是11000(一共30个0)00,也就是最高2位标识mode,其余位标识size。
接下来回到getDefaultSize函数
通过这个类的方法从参数measureSpec中提取出了specMode和specSize。 specMode的作用在下面的switch语句中可以看出来。
- case MeasureSpec.UNSPECIFIED:
- result = size;
- break;
- case MeasureSpec.AT_MOST:
- case MeasureSpec.EXACTLY:
- result = specSize;
- break;
简单示例:
OK,现在应该理解了吧,下面是一个调用measure方法的示例:
- mTextView.measure(MeasureSpec.EXACTLY + mTextView.getWidth(), MeasureSpec.EXACTLY);
- mTextView.layout(0, 0, mTextView.getMeasuredWidth(), mTextView.getMeasuredHeight());
当然,measure完后,并不会实际改变View的尺寸,需要调用View.layout方法去进行布局。按示例调用layout函数后,View的大小将会变成你想要设置成的大小。
另外关于layout,包括整个布局流程,我将要写另一篇博文介绍。因此在这里就不再赘述了。
- 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详解
- Android获取View的宽高与View.measure详解
- Android获取View的宽高与View.measure详解
- View 的 measure 方法
- view 的 measure方法
- Android中measure过程、view绘制原理和MeasureSpec介绍及使用详解
- android View.measure
- Android View measure过程
- android View.measure()初探
- 验证码图片显示不了,并且抛出bufferedimage之类的exception
- jquery autocomplete控件的试用
- Google Ips
- IOS 程序升级--文件保留情况
- linux CVS服务的用户管理
- android中View.measure方法详解
- skype 多开
- 黑马程序员java基础单例模式设计、继承与接口知识整合
- 获取指定字符串出现的次数
- 驱动程序INF文件详解
- BoneCP数据连接池 配置
- 计算机硬件组成
- 中颖内带LCD资源驱动代码
- 二分查找 三分查找