自定义View中的onMeasure,measureChild与measureChildren

原创 2015年07月07日 23:36:27

在重写的onMeasure的时候我们会调用super.onMeasure(widthMeasureSpec, heightMeasureSpec);

来一起看下源码:

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
                getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
    }
原来就是默认的为我们调用了setMeasuredDimension(设置控件需要绘制的大小),英文是Measure测量其实就可以理解为计算并设置出该控件需要的大小。

继续来看setMeasuredDimension方法

protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) {
        boolean optical = isLayoutModeOptical(this);
        if (optical != isLayoutModeOptical(mParent)) {
            Insets insets = getOpticalInsets();
            int opticalWidth  = insets.left + insets.right;
            int opticalHeight = insets.top  + insets.bottom;

            measuredWidth  += optical ? opticalWidth  : -opticalWidth;
            measuredHeight += optical ? opticalHeight : -opticalHeight;
        }
        mMeasuredWidth = measuredWidth;
        mMeasuredHeight = measuredHeight;

        mPrivateFlags |= PFLAG_MEASURED_DIMENSION_SET;
    }
isLayoutModeOptical返回的boolean类型,返回的是是否超出了我们的视觉边界,大家使用的时候都知道我们要传入的widthMeasureSpec, heightMeasureSpec是父控件的宽和高,这里就解释了为什么我们需要传入这两个值了,就是为了控制不超出父控件的大小


现在来看看measureChild和measureChildren:

measureChild是用来测量子View的宽高(我更倾向于理解为设置子View的宽高)。

measureChild(View child, int parentWidthMeasureSpec,int parentHeightMeasureSpec);

见源码

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

getChildMeasureSpec有三个参数,第一个是需要的大小(这里传的父控件的长宽,与上面的OnMeasure原理类似),第二个是当前子View的padding大小,第三个是此子View当前想要的设置的大小。

child.measure就是计算并设置出该child需要的大小。


所以每次我们在自定义View中得到测量(按英文就是测量...)子View的宽和高之后可以直接得到子View的宽高。


<span style="white-space:pre">			</span>View child = getChildAt(i);
			// 测量子View的宽和高
			measureChild(child, widthMeasureSpec, heightMeasureSpec);
			// 得到LayoutParams
			MarginLayoutParams lp = (MarginLayoutParams) child
					.getLayoutParams();

			// 子View占据的宽度
			int childWidth = child.getMeasuredWidth() + lp.leftMargin
					+ lp.rightMargin;
			// 子View占据的高度
			int childHeight = child.getMeasuredHeight() + lp.topMargin
					+ lp.bottomMargin;


measureChildren是用来测量所有子View的宽高。

理解起来很简单:

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);
            }
        }
    }
就是遍历所有的children,当不是GONE时调用measureChild方法...


最近开始看源码之后,发现以前好多看视频看书不知道的地方都可以直接理解了,大部分的教程都只会教你怎么调用而不告诉你原因,所以就学了忘,忘了再看,看了一遍又一遍,效率极低...


上面博客有什么错误的地方希望大家指正,有不理解的可以一起交流大笑


版权声明:本文为博主原创文章,未经博主允许不得转载。

measureChildren的工作原理

无论是在重写View还是ViewGroup的时候,尤其是ViewGrop的时候,往往不可避免的重写onMeasure方法,我们一定会调用setMeasuredDimension()将测量好的宽高值传递...

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

在View.java中的定义: public final void measure(int widthMeasureSpec, int heightMeasureSpec){ ...  onMe...

Android onMeasure、Measure、measureChild、measureChildren 的一些区别

androidonmeasure在View.java中的定义: public final void measure(int widthMeasureSpec,int heightMeasureS...

Android自定义视图系列----------- 计算view大小(measure)

1.android绘制view的过程简单描述            简单描述可以解释为:计算大小(measure),布局坐标计算(layout),绘制到屏幕(draw);            下面看...

View工作原理(三)视图大小计算过程(measure过程)

一、android视图measure过程总概 视图大小计算的过程是从根视图measure()方法开始,接着该方法会调用根视图的onMeasure()方法,onMeasure()方法会对所包含的子视图...

Android ViewGroup测量child过程

ViewGroup测量child的过程 1.UNSPECIFIED 2.EXACTLY 3.AT_MOST
  • csm_qz
  • csm_qz
  • 2015年12月26日 12:31
  • 1012

Android进阶系列0—View的工作流程:measure,layout,draw小结

本文主要来自《Android开发艺术探索》和郭霖 《Android视图绘制流程完全解析,带你一步步深入了解View(二)》 两部分的综合理解。 本文只阐述流程,不讲述细节,大家可以结合上述两部分的细...

ViewGroup.measureChildWithMargins() 学习笔记

VIew 中对 子视图 进行 measure() 操作:
  • abwbw
  • abwbw
  • 2014年10月17日 14:22
  • 4126

Android自定义View(三、深入解析控件测量onMeasure)

转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51468648 本文出自:【openXu的博客】 目录:onMeasure什么...

自定义view onMeasure方法的重写

内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:自定义View中的onMeasure,measureChild与measureChildren
举报原因:
原因补充:

(最多只允许输入30个字)