onMeasure和Measure

作者: 卜卜Bruce | 来源:发表于2018-04-05 20:40 被阅读12次

    先来看看官方文档对方法的描述。

    onMeasure

    void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
    测量View和它的内容来确定measured width和measured height,这个方法被measure(int, int)调用,而且会被子类重写来准确高效的测量他们的内容。
    约定事项: 当重写这个方法的时候,必须调用setMeasuredDimension(int, int)来存储这个View的measured width和measured height,否则measure(int, int)会触发 IllegalStateException。直接使用父类的on measure(int, int)是可以的。

    基类默认是测量背景的尺寸(看下面源码)。子类应该重写'onMeasuer(int, int)' 来提供更好的测量方法来测量他们的内容。
    如果这个方法被重写,它的子类要保证测量高度和宽度至少是view的最小高宽。

     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;
        }
    
    //获取背景的最小宽
    protected int getSuggestedMinimumWidth() {
            return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());
        }
    //获取背景的最小高
    protected int getSuggestedMinimumHeight() {
            return (mBackground == null) ? mMinHeight : max(mMinHeight, mBackground.getMinimumHeight());
    
        }
    

    Measure

    void measure (int widthMeasureSpec, int heightMeasureSpec)
    找出View有多大的时候调用这个方法,参数是父类提供的约束信息。
    实际的测量工作是在通过调用onMeasure(int, int)完成的。因此只有‘onMeasure(int, int)’能被重写。

    下面看看MeasureSpec的参数,MeasureSpec包含大小和模式,它有3种模式:

    UNSPECIFIED,父控件不强制约束子控件,子控件可以任意大小;

    EXACTLY,父控件已经给子控件的一个确定的大小,无论子控件多大都被限制在这个边界内

    AT_MOST,子控件至多达到指定大小。
    父控件的约束规则 子控件的宽高属性 子控件的约束规则 说明
    EXACTLY(父控件是填充父窗体,或者具体size值) 具体的size(20dip)/MATCH_PARENT EXACTLY 子控件如果是具体值,约束尺寸就是这个值,模式为确定的;子控件为填充父窗体,约束尺寸是父控件剩余大小,模式为确定的。

    父控件的约束规则 子控件的宽高属性 子控件的约束规则 说明
    EXACTLY(父控件是填充父窗体,或者具体size值) 具体的size(20dip)/MATCH_PARENT EXACTLY 子控件如果是具体值,约束尺寸就是这个值,模式为确定的;子控件为填充父窗体,约束尺寸是父控件剩余大小,模式为确定的。
    WRAP-CONTENT AT_MOST 子控件如果是包裹内容,约束尺寸值为父控件剩余大小 ,模式为至多
    AT_MOST(父控件是包裹内容) 具体的size(20dip) EXACTLY 子控件如果是具体值,约束尺寸就是这个值,模式为确定的;
    MATCH_PARENT/WRAP_CONTENT AT_MOST 子控件为填充父窗体或者包裹内容 ,约束尺寸是父控件剩余大小 ,模式为至多
    UNSPECIFIED(父控件未指定) 具体的size(20dip) EXACTLY 子控件如果是具体值,约束尺寸就是这个值,模式为确定的;
    MATCH_PARENT/WRAP_CONTENT UNSPECIFIED 子控件为填充父窗体或者包裹内容 ,约束尺寸0,模式为未指定

    参考:https://blog.csdn.net/xmxkf/article/details/51490283

    相关文章

      网友评论

        本文标题:onMeasure和Measure

        本文链接:https://www.haomeiwen.com/subject/ajtrhftx.html