第一步
从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次 |