自定义view如下:
public class MyView extends View {private static final int DEFAULT_WIDTH = 100;private static final int DEFAULT_HEIGHT = 100;private Paint paint;private Rect rect;public MyView(Context context) {super(context);init();}public MyView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);init();}public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}private void init() {paint = new Paint();paint.setColor(Color.parseColor("#ff0000"));rect = new Rect(getPaddingLeft(), getPaddingTop(), 200, 200);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int width = getProperSize(DEFAULT_WIDTH, widthMeasureSpec);int height = getProperSize(DEFAULT_HEIGHT, heightMeasureSpec);setMeasuredDimension(width, height);}private int getProperSize(int defaultSize, int measureSpec) {int result;int mode = MeasureSpec.getMode(measureSpec);int size = MeasureSpec.getSize(measureSpec);if (mode == MeasureSpec.EXACTLY) {result = size;} else {result = defaultSize;if (mode == MeasureSpec.AT_MOST) {result = Math.min(result, size);}}return result;}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawRect(rect, paint);}}
onMeasure与onSizeChanged获取尺寸区别:
获取的尺寸单位均为px
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int width = getWidth();int height = getHeight();int measuredHeight = getMeasuredHeight();int measuredWidth = getMeasuredWidth();int suggestedMinimumWidth = getSuggestedMinimumWidth();int suggestedMinimumHeight = getSuggestedMinimumHeight();
}@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);int width = getWidth();int height = getHeight();int measuredHeight = getMeasuredHeight();int measuredWidth = getMeasuredWidth();int suggestedMinimumWidth = getSuggestedMinimumWidth();int suggestedMinimumHeight = getSuggestedMinimumHeight();
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);源码:
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;
}
可看出:
wrap_content和match_parent具有相同的效果,即填充父容器
getSuggestedMinimumWidth方法源码:
private int mMinWidth;
private int mMinHeight;private Drawable mBackground;protected int getSuggestedMinimumWidth() {return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());
}protected int getSuggestedMinimumHeight() {return (mBackground == null) ? mMinHeight : max(mMinHeight, mBackground.getMinimumHeight());}