onMeasure和Measure

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

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_PARENTEXACTLY子控件如果是具体值,约束尺寸就是这个值,模式为确定的;子控件为填充父窗体,约束尺寸是父控件剩余大小,模式为确定的。
WRAP-CONTENTAT_MOST子控件如果是包裹内容,约束尺寸值为父控件剩余大小 ,模式为至多
AT_MOST(父控件是包裹内容)具体的size(20dip)EXACTLY子控件如果是具体值,约束尺寸就是这个值,模式为确定的;
MATCH_PARENT/WRAP_CONTENTAT_MOST子控件为填充父窗体或者包裹内容 ,约束尺寸是父控件剩余大小 ,模式为至多
UNSPECIFIED(父控件未指定)具体的size(20dip)EXACTLY子控件如果是具体值,约束尺寸就是这个值,模式为确定的;
MATCH_PARENT/WRAP_CONTENTUNSPECIFIED子控件为填充父窗体或者包裹内容 ,约束尺寸0,模式为未指定

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

转载于:https://juejin.im/post/5c875359e51d453a9e7ed27a

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值