自定义控件的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); }
好了今天如此详细的讲解了这个方法的作用及其参数的作用,大家自己也去试试吧
相关文章推荐
- Unity 2D 闪电特效
- Caches 《ARM System Developer's Guide》chapter-12
- 借道IIS搭建企业内部Web方式文件共享平台
- Sona
- android中的进程和线程
- Andorid 10 个最常见的 React Native Android 问题
- Java随机密码生成并和邮箱、手机号匹配
- 2016太原网络营销师郭文军分享所带学员在达内的成长?
- Yarn资源分配性能调优
- ZOJ1024-Calendar Game
- Leetcode[110]-Balanced Binary Tree
- C# 类的序列化和反序列化
- C语言中的指针学习(小黑板)
- 两个数组找相同
- iOS下载大文件原理解析一
- win7用控制台本地组策略自定义程序(任意文件)开机自动启动
- 智能硬件公司估值集体缩水 资本疯狂涌入VR
- SQL 查询 日期
- 复杂对象的组装与创建——建造者模式
- LeetCode Text Justification