您的位置:首页 > 其它

自定义控件的onMeasure方法详解

2016-01-28 10:22 549 查看

在我们自定义控件的时候可能你会用到onMeasure方法,下面就详细的给大家介绍一下这个方法:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}


我们自定义一个类继承View或者ViewGroup之后重写onMeasure方法,我们看到这个方法传递进来两个变量,这里做一下解释:
widthMeasureSpec:推荐的宽度和宽度的计算模式

heightMeasureSpec:推荐的高度和高度的计算模式

这里为什么说是推荐的宽和高呢?
因为这个方法是测量的作用,顾名思义就是让你测量一下你自身的宽和高,传递进来的变量只是提供你作为参考,你根据这些参考值来计算你自身的宽和高!

那么有的人又有疑问了,你说的上面两个值的意思是推荐的宽和高以及响应的计算模式,可我怎么就看到两个值啊,你说的明明就是四个嘛?
这是因为一个变量里面包含了两个变量的值,所以我们需要对这两个值进行操作,获取相应的宽和高和对应的计算模式

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);

// 宽和高的计算模式
int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
int modeHeight = MeasureSpec.getMode(heightMeasureSpec);
//真正的宽和高的数值
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
int sizeHeigth = MeasureSpec.getSize(heightMeasureSpec);

measureChildren(widthMeasureSpec, heightMeasureSpec);

setMeasuredDimension(sizeWidth, sizeHeigth);

}


可以看到我们通过类MeasureSpec的静态方法可以获取到相应的计算模式和宽和高
其实计算模式就是你在布局文件中写的match_parent、wrap_content
而获取出来的宽和高是当前的计算模式下父容器所能给你的最大宽和高
比如:
父容器320*480
你这个控件的宽和高用了match_parent
那么这里推荐你的宽和高就是320*480
计算模式就是一个match_parent常量:
ViewGroup.LayoutParams.MATCH_PARENT




假如你用了wrap_content,那么这里推荐你的宽和高还是320*480
计算模式就是一个wrap_content常量:

ViewGroup.LayoutParams.WRAP_CONTENT




为什么推荐的宽和高和match_parent的时候一样,因为父容器无法确定你的包裹内容的需要的宽和高具体是多少,所以它只能给你它最大的.所以这个方法计算的时候其实说白了就是计算包裹内容的时候自身的大小,因为无论是match_parent还是写死的大小父容器都能很轻松的算出来你需要的大小,只有在包裹的时候是不知道的,需要你自己计算,然后通知我,如何通知呢?

通过方法:setMeasureDimension(int,int)来告知,这里面就是传入你计算好的真正的宽和高.所以在不是包裹内容的时候父容器推荐你的宽和高是正确的,你无须计算,直接走父类的方法即可,所以一般的解决方法就是下面这样:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// 宽和高的计算模式
int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
int modeHeight = MeasureSpec.getMode(heightMeasureSpec);
//拿到父容器推荐的宽和高
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
int sizeHeigth = MeasureSpec.getSize(heightMeasureSpec);
<span style="white-space:pre">	</span>//这里测量每一个孩子的宽和高
if (modeWidth == MeasureSpec.ATMOST)
//sizeWidth = 计算的值
}
if (modeHeight == MeasureSpec.ATMOST<span style="font-family: Arial, Helvetica, sans-serif;">)</span>
//sizeHeigth = 计算的值
}
setMeasuredDimension(sizeWidth, sizeHeigth);
}


好了今天如此详细的讲解了这个方法的作用及其参数的作用,大家自己也去试试吧
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: