因为一直都记不住onMeasure的过程,不知道自定义view的时候该怎么复写onMeasure。所以就试着写一次下来,增强一下记忆力。
View中的onMeasure:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec), getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec)); }这是View中的onMeasure,我们可以看到只有一个方法setMeasuredDimension()。所以这个方法就是直接设置View的大小的。
setMeasuredDimension:
最后会调用setMeasuredDimensionRaw设置大小
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; } setMeasuredDimensionRaw(measuredWidth, measuredHeight); }
getDefaultSize:
从源码中我们可以知道,当测量模式是Unspecified的时候,返回的是接收的第一个参数size,当测量模式是At_MOST或者是EXACTLY的时候,返回的值是系统测量得到的值。
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; }所以我们知道了,要复写onMeasure的时候我们最后要把大小传给setMeasuredDimesion;