我们在自定义控件的时候,通常会涉及到测量的问题,onMeasure方法就是让我们的控件测量自身的一个方法,这里给出系统自带的一个现成的方法:
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); }
博客发现一个容易引起误解的地方:就是这个方法所使用的参数名字,parentWidth....这样子的参数意思就是说父容器宽的Measure 或者 高的Measure 而这里的用处完全是孩子用到的,所以这里博客认为这个参数的名称起的有问题,比较容易引起误解,如果哪位大大知道我说的有错误,还请指正,欢迎留言给我!
public static int getChildMeasureSpec(int spec, int padding, int childDimension) { //...... }由于代码比较长,故不贴出中间的实现了,这个方法是根据推荐的spec(宽或高计算模式和宽或高的值),padding(左边距+右边距),chileDimension(孩子的宽或者高的值,可以是LayoutParams.WRAP_CONTENT(包裹),LayoutParams.MATCH_PARENT(填充))
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; }