自定义控件测量的深究

第一步

从MeasureSpec对象中提取出具体的测量模式和大小

private int getMeasureSize(int measureSpec) {
        int result=0;
        int specMode= MeasureSpec.getMode(measureSpec);
        int specSize= MeasureSpec.getSize(measureSpec);
        if(MeasureSpec.AT_MOST==specMode) {//尽可能的大
            result = Math.min(result,specSize);
            Log.i("yupeng","AT_MOST:"+result);
        }else if(MeasureSpec.EXACTLY==specMode){ //精确测量模式
            result = specSize;
            Log.i("yupeng","EXACTLY:"+result);
        }else if(MeasureSpec.UNSPECIFIED==specMode){//要多大有多大模式
            result=specSize;
            Log.i("yupeng","UNSPECIFIED:"+result);
        }
       return result;
    }
第二步

将测量到的尺寸在onMeasure()中设置即可

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        Log.i("yupeng","要测量宽度啦");
        int width=getMeasureSize(widthMeasureSpec);
        Log.i("yupeng","要测量高度啦");
        int height=getMeasureSize(heightMeasureSpec);
        Log.i("yupeng","要设置测量结果啦");
        setMeasuredDimension(width,height);
    //  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

由于是自定义控件测量,所以屏蔽了父类的测量方法,最后调用
setMeasureDimension(Width,height)方法将尺寸设置即可。

为了弄清楚layout布局中尺寸参数对测量模式的影响,特地进行了测试
当布局中view的宽高设置为wrap_content时
这里写图片描述

这是描述

当布局中view的宽高设置为match_parent时
这里写图片描述

这里写图片描述

当布局中view的宽高设置为固定数值时
这里写图片描述

这里写图片描述

经测试发现,当layout属性设置为match_parent或者固定尺寸时,获取到的测量模式为EXACTLY,即精确测量

当layout属性设置为warp_content时,获取到的测量模式为AT_MOST

因为match_parent与固定尺寸都是EXACTLY,再做测试,将父布局的尺寸固定死,固定为100dp,在进行match_parent,与固定尺寸测试
当尺寸固定为200dp时
这里写图片描述

这里写图片描述

测量方法被执行了四次,最终被限制为父布局的大小。而不是控件设置的大小。而且四次测量的结果不相同。
当尺寸为match_parent时
这里写图片描述

这里写图片描述

由于测量方法onMeasure()的

测量方法执行了四次,测量结果始终是父布局的大小,并且四次测量的结果相同。

关于测量方法的执行次数,经过多次测试,发现与其父布局有关,多个父布局嵌套执行次数相加
测试结果如下

view外部onMeasure()
1个relativeLayout执行4次
2个relativeLayout执行8次
view外部onMeasure()
1个linearLayout执行2次
2个linearLayout执行2次
view外部onMeasure()
1个frameLayout执行2次
2个frameLayout执行2次
view外部onMeasure()
1个tableLayout执行2次
2个tableLayout执行2次

其中”1个”,”2个”意思是layout嵌套,如下图就是2个tableLayout
这里写图片描述

关于不同layout的嵌套

如果其中RelativeLayout比较特殊,如果是RelativeLayout与别的layout嵌套,则只会将RelativeLayout的测量次数进行叠加,不再进行别的布局的测量,如果其余布局嵌套,则只会测量两次
测试记录如下,其中R-RelativeLayout L-LinearLayout T-TableLayout

view外部onMeasure()
L-R-L执行4次
R-R-L执行8次
R-L-R执行8次
view外部onMeasure()
R-T-R执行8次
T-R-T执行4次
view外部onMeasure()
L-T-L执行2次
T-L-T执行2次
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值