用户主动调用 request,只会出发 measure 和 layout 过程,而不会执行 draw 过程
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int viewWidth = circleRadius + this.getPaddingLeft() + this.getPaddingRight();
int viewHeight = circleRadius + this.getPaddingTop() + this.getPaddingBottom();
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
//Measure Width
if (widthMode == MeasureSpec.EXACTLY) {
//Must be this size
width = widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
width = Math.min(viewWidth, widthSize);
} else {
//Be whatever you want
width = viewWidth;
}
//Measure Height
if (heightMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.EXACTLY) {
//Must be this size
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
height = Math.min(viewHeight, heightSize);
} else {
//Be whatever you want
height = viewHeight;
}
setMeasuredDimension(width, height);
}
measure的核心方法
- measure(int widthMeasureSpec,int heightMeasureSpec):是view中final方法,不能重写,但是最终都会曲调用onMeasure方法
- onMeasure(int widthMeasureSpec,int heightMeasureSpec):发方法中两个参数是父控件对子view的测量要求,在该方法中需要结合测量模式和测量大小以及边界距离值确定view的最终大小
- setMeasureDimension(int width,int height):在onMeasure中得到最终的大小之后,一定要调用这个方法进行最终的确定,否则会报错。
mCustomView.setPadding(0, top, 0, 0);等方法最终也会去调用requestLayout,调整padding的值,其中参数负数则代表反方向。