版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/izzxacbbt/article/details/84400602
在Android中,onMeasu的源码
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}
这里主要是getDefaultSize方法,我们看一下这个的源码
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;
}
可以看到,这个东西还是比较简单的,如果是未确切的则使用传过来的第一个参数,否则都是使用父类给他的specsize,那么,第一个参数是什么我们也需要去看一下
protected int getSuggestedMinimumWidth() {
return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());
}
上面就是传给getDefaultSize的第一个参数,这个函数的意思是,如果有背景则使用背景大小和允许的最小size中较大的一个,如果没有背景则直接使用最小size.
接下来再看一下getDefaultSize的第二个参数,即父类设置的MeasureSpec
父类根据自己的MeasureSpec和子类参数决定子类的MeasureSpec
如果子类是确切的大小,则他的MeasureSpec是固定的,
在自定义view中我们经常需要实现wrapcontent参数,而细想一下,其实就是当需要使大小设置为自己需要的width和height,那么如何实现呢?问题的关键在于,当我们设置为wrapcontent时候,他的值会是AT_MOST,当然还有一个UNSPERCIFIED,不过因为我们的布局文件中一般viewgroup不会出现UNSPERCIFIED所以不需要考虑这个,也就是说我们只需要在getDefaultSize中考虑一下AT_MOST的情况,将AT_MOST的情况和EXACTLY的情况分开,不过光是这样还不够,因为可以看到当父类是AT_MOST时候match_parent也是AT_MOST,wrap_content分出来考虑,而match_parent的情况则和原来EXACTLY的情况一样设置为参数二中的数值即可.