onMeasure、Measure、measureChild、measureChildren 一些简要说明

在View.java中的定义:

public final void measure(int widthMeasureSpec,int heightMeasureSpec){

...

onMeasure

...

}

protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec) {

setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),

getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));

}

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

在ViewGroup中:

   protected void measureChildren(int widthMeasureSpec, int heightMeasureSpec) {
        final int size = mChildrenCount;
        final View[] children = mChildren;
        for (int i = 0; i < size; ++i) {
            final View child = children[i];
            if ((child.mViewFlags & VISIBILITY_MASK) != GONE) {
                measureChild(child, widthMeasureSpec, heightMeasureSpec);
            }
        }
    }
   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);
    }
 protected void measureChildWithMargins(View child,
            int parentWidthMeasureSpec, int widthUsed,
            int parentHeightMeasureSpec, int heightUsed) {
        final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();

        final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
                mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin
                        + widthUsed, lp.width);
        final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
                mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin
                        + heightUsed, lp.height);

        child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
    }

说明:

1. measure是final修饰的方法,不可被重写。

在外部调用时,直接调用view.measure(int wSpec, int hSpec)。

measure中调用了onMeasure。

自定义view时,重写onMeasure即可。

2.MeasureSpec 这是一个含mode和size的结合体,不需要我们来具体的关心。

当在测量时,可以调用MeasureSpec.getSize|getMode 得到相应的size和mode。

然后使用MeasureSpec.makeMeasureSpec(size,mode); 来创建MeasureSpec对象。

那么mode是怎么来的呢?是根据使用该自定义view时的layoutWith|height参数决定的,所以不能自己随便new一个。

而size可以自己指定,也可以直接使用 measureSpec.getSize。

3.如果是一个View,重写onMeasure时要注意:

如果在使用自定义view时,用了wrap_content。那么在onMeasure中就要调用setMeasuredDimension,

来指定view的宽高。如果使用的fill_parent或者一个具体的dp值。那么直接使用super.onMeasure即可。

4.如果是一个ViewGroup,重写onMeasure时要注意:

首先,结合上面两条,来测量自身的宽高。

然后,需要测量子View的宽高。

测量子view的方式有:

getChildAt(int index).可以拿到index上的子view。

通过getChildCount得到子view的数目,再循环遍历出子view。

接着,subView.measure(int wSpec, int hSpec); //使用子view自身的测量方法

或者调用viewGroup的测量子view的方法:

//某一个子view,多宽,多高, 内部加上了viewGroup的padding值

measureChild(subView, int wSpec, int hSpec);

//所有子view 都是 多宽,多高, 内部调用了measureChild方法

measureChildren(int wSpec, int hSpec);

//某一个子view,多宽,多高, 内部加上了viewGroup的padding值、margin值和传入的宽高wUsed、hUsed

measureChildWithMargins(subView, intwSpec, int wUsed, int hSpec, int hUsed);

时间: 2024-10-30 07:20:22

onMeasure、Measure、measureChild、measureChildren 一些简要说明的相关文章

Android View measure (二) 自定义UI控件measure相关

本篇模拟三个角色:Android 架构师-小福.Android  控件开发工程师-小黑. Android 开发工程师-小白,下面按照三个角色不同角度分析measure过程. 小福负责分享: measure的本质 measure代码流程 onMeasure方法与MeasureSpec 提出问题 小黑负责分享: 布局控件开发中覆写Measure例子 - ok 从遇到的一个异常说起 什么时候需要覆写onMeaure? - ok view.getWidth与view.getMeasureWidth区别

Android View measure (一) 流程分析

本篇模拟三个角色:Android 架构师-小福.Android  控件开发工程师-小黑. Android 开发工程师-小白,下面按照三个角色不同角度分析measure过程. 小福负责分享: measure的本质 - ok measure代码流程 - 分析FrameLayout.onMeasure onMeasure方法与MeasureSpec - ok 提出问题 Android 架构师-小福的分享 一.Measure本质 小福:我今天分享是的measure架构设计相关的,先问一个问题,measu

Android自定义控件系列八:详解onMeasure()(二)--利用onMeasure测量来实现图片拉伸永不变形,解决屏幕适配问题

上一篇文章详细讲解了一下onMeasure/measure方法在Android自定义控件时的原理和作用,参看博文:Android自定义控件系列七:详解onMeasure()方法中如何测量一个控件尺寸(一),今天就来真正实践一下,让这两个方法大显神威来帮我们搞定图片的屏幕适配问题. 请尊重原创劳动成果,转载请注明出处:http://blog.csdn.net/cyp331203/article/details/45038329,非允许请勿用于商业或盈利用途,违者必究. 使用ImageView会遇到

【Android高级】CSDN博客精华知识讲解汇总

1.Activity的启动方式和flag详解  from(任玉刚) 2.android_WebView与Javascript的交互 from(redarmychen的专栏) 3.android-async-http开源项目from(redarmychen的专栏) 4.HTML实训课程笔记 from(redarmychen的专栏) 5.防止Android程序被系统kill掉的处理方法  from(小崔的博客) 6.直接拿来用!最火的Android开源项目系列 from(徐刘根的专栏) 7.安卓框架

Android-视图绘制

http://blog.csdn.net/guolin_blog/article/details/16330267 任何一个视图都不可能凭空突然出现在屏幕上,它们都是要经过非常科学的绘制流程后才能显示出来的.每一个视图的绘制过程都必须经历三个最主要的阶段,即onMeasure().onLayout()和onDraw(),下面我们逐个对这三个阶段展开进行探讨. onMeasure()用于测量视图大小 onLayout()用于确定视图位置 onDraw()用于绘制视图 一. onMeasure()

LayoutInflater(二)

每一个视图的绘制过程都必须经历三个最主要的阶段,即onMeasure().onLayout()和onDraw(),下面我们逐个对这三个阶段展开进行探讨. 一. onMeasure() measure是测量的意思,那么onMeasure()方法顾名思义就是用于测量视图的大小的.View系统的绘制流程会从ViewRoot的performTraversals()方法中开始,在其内部调用View的measure()方法.measure()方法接收两个参数,widthMeasureSpec和heightM

Android视图绘制流程完全解析,带你一步步深入了解View(二)

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/16330267 在上一篇文章中,我带着大家一起剖析了一下LayoutInflater的工作原理,可以算是对View进行深入了解的第一步吧.那么本篇文章中,我们将继续对View进行深入探究,看一看它的绘制流程到底是什么样的.如果你还没有看过我的上一篇文章,可以先去阅读 Android LayoutInflater原理分析,带你一步步深入了解View(一) . 相 信每个Android

Android--自定义ViewGroup()

Measure的本质是:把试图布局时的相对值转化为具体值. MeasureSpec类包装了从parent传递下来的布局要求,每一个MeasureSpec代表了对宽度和高度的一个要求. 为什么布局需要父视图与子视图共同决定? 为什么不直接设置宽和高? 如果不这样就像HTML那样指定固定大小,这样会造成一个过大把另外一个挤出去.因为HTML是具有整个页面的控制权. 而Android是拆分开的,这样做保证了最末端的(界面开发)影响其他层级的布局,需要按照(控件开发)的规则来. view.setWidt

Android 深入了解View(二)

相信每个Android程序员都知道,我们每天的开发工作当中都在不停地跟View打交道,Android中的任何一个布局.任何一个控件其实都是直接或间接继承自View的,如TextView.Button.ImageView.ListView等.这些控件虽然是Android系统本身就提供好的,我们只需要拿过来使用就可以了,但你知道它们是怎样被绘制到屏幕上的吗?多知道一些总是没有坏处的,那么我们赶快进入到本篇文章的正题内容吧. 要知道,任何一个视图都不可能凭空突然出现在屏幕上,它们都是要经过非常科学的绘