View体系(八)深入剖析View的onMeasure方法

之前的文章《View体系(六)View工作流程入口》介绍了View是从什么地方开始它的工作流程的,《View体系(七)理解 MeasureSpec》介绍了Viewmeasure流程时的一个重要参数。有了上两篇的铺垫,我们就来看一下ViewonMeasure方法到底做了什么。

(注:文中源码基于 Android 12

View做测量时,会调用ViewonMeasure方法:

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
                getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
    }

这里只调用了一个setMeasuredDimension方法,看它的注释:

This method must be called by {@link #onMeasure(int, int)} to store the measured width and measured height.

可以知道,这个方法是用来存储测量的宽度和测量的高度的。

继续看setMeasuredDimension方法里面调用了getDefaultSize,该方法用于获取View默认的大小:

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

specModespecSize之前的文章中讲过,表示测量模式和测量大小。这段代码表示根据不同的specMode来返回不同的result值,即View测量的大小。可以看到注释处不管是AT_MOST还是EXACTLY,都返回specSize,也就是说,对于一个直接继承自View的自定义View来说,它的wrap_contentmatch_parent属性的效果是一样的。因此我们自定义View时,如果要使wrap_content属性生效,就必须重写onMeasure方法并根据specMode来返回指定的大小。

现在我们知道了specSize是测量的大小,那传入的第一个参数size又是个什么?我们看传入的getSuggestedMinimumWidth方法做了什么:

    protected int getSuggestedMinimumWidth() {
        return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());
    }

这里先判断View是否有背景,如果有,就返回背景宽度和View最小宽度中较大的一个;如果没有,就直接返回View的最小宽度,即mMinWidth。默认的mMinWidth为0,对应xml文件中的android:minWidth属性。

至此,ViewonMeasure方法我们就分析完了,其做的工作很简单,就是保存View的测量尺寸。在我们自定义View时,我们根据自己的需求来重写onMeasure方法,并对View的尺寸自己进行测量并调用setMeasuredDimension方法进行保存。

学习更多知识,请关注我的个人博客:droidYu

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值