View的测量onMeasure方法
2016-12-29 08:43
218 查看
View的测量
自定义View的时候,一般都会涉及到View的几个方法,onDraw、onMeasure和onLayout等方法,依照顺序走的话,会先走onLayout——onMeasure——onDraw,其中onLayout方法主要是处理该View在父布局当中的坐标位置,onMeasure方法是测量该View的大小宽高,最后onDraw方法则是把该View的内容绘制出来。这里要讲述的就是onMeasure方法
说到View的onMeasure方法,就要说一下MeasureSpec这个类,这个类我对它的理解就是View测量的规格类,指定了几种模式:EXACTLY,AT_MOST,UNSPECIFIED。
- EXACTLY:准确的、精确的;这种模式,是最容易理解和处理的,可以理解为大小固定,比如在定义layout_width的时候,定义为固定大小 10dp,20dp,或者match_parent(此时父控件是固定的)这时候,获取出来的mode就是EXACTLY
- AT_MOST:最大的;这种模式稍微难处理些,不过也好理解,就是View的大小最大不能超过父控件,超过了,取父控件的大小,没有,则取自身大小,这种情况一般都是在layout_width设为warp_content时
- UNSPECIFIED:不指定大小,这种情况,我们几乎用不上,它是什么意思呢,就是View的大小想要多大,就给多大,不受父View的限制,几个例子就好理解了,ScrollView控件就是
我们来看看对于View的该方法我是怎么重写的
/** * 整个view内容的宽高 */ private int contentWidth; private int contentHeight; private void initView(AttributeSet attrs) { } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // super.onMeasure(widthMeasureSpec, heightMeasureSpec); //先利用MeasureSpec得到宽高的mode int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); //利用MeasureSpec得到宽高的size int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); //最后要设置的宽高 int width; int height; //我们期待的宽高 int desiredWidth = getPaddingLeft() + getPaddingRight() + contentWidth; int desiredHeight = getPaddingTop() + getPaddingBottom() + contentHeight; //根据模式来对我们需要设置的宽高进行判断 switch (widthMode) { case MeasureSpec.AT_MOST: width = Math.min(widthSize, desiredWidth); break; case MeasureSpec.UNSPECIFIED: width = desiredWidth; break; default: case MeasureSpec.EXACTLY: width = widthSize; break; } switch (heightMode) { case MeasureSpec.AT_MOST: height = Math.min(heightSize, desiredHeight); break; case MeasureSpec.UNSPECIFIED: height = desiredHeight; break; default: case MeasureSpec.EXACTLY: height = heightSize; break; } //调用父类的测量方法 setMeasuredDimension(width, height); }
总结:
对于自定义View,只要对onMeasure和onDraw这两个方法比较熟悉的话,基本上都可以完成一些复杂View的定义,而onMeasure方法的话,只要对MeasureSpec类比较熟悉的,基本上也不会出现问题了相关文章推荐
- 浅谈CPU和GPU的区别
- linux grep命令详解
- C#怎么实现文件下载功能
- C#-WebForm-点击网页中的按钮后跳转到其他页面是怎么实现的?
- Oracle Linux 6.6系统卡在进度条界面
- 赵忠祥五亿豪宅内景曝光 奢华装修堪比皇宫
- linux 内核/用户空间获取时间
- php使用正则表达式获取字符串中的URL
- webgl教程
- 8.事件 事件发布程序
- PAT-乙级-1013
- vsftpd虚拟用户目录及权限分离
- php实现水印文字和缩略图的方法示例
- mysql-5.7.9安装
- NFS服务配置
- 为Unity编写C++ Native Plugin
- myrocks复制中断问题排查
- java并行计算Fork和Join的使用
- Weex开发之路(1):开发环境搭建
- 用mapreduce计算wordCount和手机流量统计程序运行过程