onMeasure与onSizeChanged获取尺寸区别

转载自: https://blog.csdn.net/sinat_31057219/article/details/80592171

自定义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);
        }
    
        @Override
        protected 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;
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    
    
            super.onSizeChanged(w, h, oldw, oldh);//可省略
        }
    
        @Override
        protected 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();
        //onMeasure中:
        //Width = Height = 0 
        //当具体数据或match_parent时:
        //measuredHeight的最后数值 = onSizeChanged中h = height = measuredHeight
        //measuredWidth的最后数值  = onSizeChanged中w = width  = measuredWidth
    
        int suggestedMinimumWidth = getSuggestedMinimumWidth();
        int suggestedMinimumHeight = getSuggestedMinimumHeight();
        //等于xml中指定的min尺寸与背景图的min尺寸中较大值,否则为零
    }
    
    @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();
        //onSizeChanged中
        //w = width  = measuredWidth
        //h = height = measuredHeight
        //oldw = onMeasure方法中getWidth()的最后数值
        //oldh = onMeasure方法中getHeight()的最后数值
    
        int suggestedMinimumWidth = getSuggestedMinimumWidth();
        int suggestedMinimumHeight = getSuggestedMinimumHeight();
        //等于xml中指定的min尺寸与背景图的min尺寸中较大值,否则为零
    }

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

猜你喜欢

转载自blog.csdn.net/qq_42420293/article/details/123315056