这里主要介绍第一步measure,measure是view大小计算的过程。先来一个自定义View的例子,演示如何覆写onMeasure方法



一、 覆写onMeasure的例子(自定义View)  






例子下载地址   自定义view全屏显示蓝色方块






1. 覆写onMeasure


[plain] view plain copy print ?


1. @Override   
2. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {   
3.   
4. }




2. 分别计算出宽高,后面解释使用的方法的作用


[plain] view plain copy print ?


1. private int measureWidth(int pWidthMeasureSpec) {  
2.     int result = 0;  
3.       
4.     int widthMode = MeasureSpec.getMode(pWidthMeasureSpec);  
5.     int widthSize = MeasureSpec.getSize(pWidthMeasureSpec);  
6.       
7.     switch (widthMode) {  
8.     case MeasureSpec.AT_MOST:  
9.     case MeasureSpec.EXACTLY:  
10.         result = widthSize;  
11.         break;  
12.     }  
13.     return result;  
14. }  
15.   
16.   
17. private int measureHeight(int pHeightMeasureSpec) {  
18.     int result = 0;  
19.       
20.     int heightMode = MeasureSpec.getMode(pHeightMeasureSpec);  
21.     int heightSize = MeasureSpec.getSize(pHeightMeasureSpec);  
22.       
23.     switch (heightMode) {  
24.     case MeasureSpec.AT_MOST:  
25.     case MeasureSpec.EXACTLY:  
26.         result = heightSize;  
27.         break;  
28.     }  
29.       
30.     return result;  
31. }




3. 调用setMeasuredDimension,指定视图在屏幕上的大小、


[plain] view plain copy print ?


1. int measureWidth = measureWidth(widthMeasureSpec);  
2. int measureHeight = measureHeight(heightMeasureSpec);  
3.   
4. setMeasuredDimension(measureWidth, measureHeight);






二、 解释例子中使用的MeasureSpec  


     MeasureSpec是一个android.view.View的内部类。





     MeasureSpec封装了从父类传送到子类的布局要求信息。每个MeasureSpec对象描述了空间的高度或宽度。 MeasureSpec由size和mode组成。





1. MeasureSpec的方法介绍:



类名.方法名

解释

MeasureSpec.getMode(int measureSpec)

根据提供的测量值(格式)提取模式(上述三个模式之一)

MeasureSpec.getSize(int measureSpec)

根据提供的测量值(格式)提取大小值(这个大小也就是我们通常所说的大小)

MeasureSpec.makeMeasureSpec(int size,int mode)

根据提供的大小值和模式创建一个测量值(格式)



2. MeasureSpec有三种mode,分别说明并描述模式与layout参数值的对应关系



模式

模式翻译

模式与Layout参数的对应关系 

android:layout_width=“” 

android:layout_height=“”

模式描述

UNSPECIFIED

无限制

 

parent view不约束child view的大小

AT_MOST

最多的

wrap_content

parent view 为child view指定最大的值,child view可以在范围内设置

EXACTLY

准确的

fill_parent,精确值(例如50dip)

parent view为child view指定固定大小




三、 疑惑



例子总只写了一个view,在onMeasure中添加log获知此方法执行2次? 在ADT 20.3中同样的代码onMeasure执行4次?不是应该只执行一次吗?





*** 待添加


1. 如果视图还未添加到ViewGroup中,还想获取其宽高,需要手动调用View.measure()方法,可以传入三种模式或者具体值


2. child.measure(MeasureSpec.EXACTLY | itemWidth, MeasureSpec.UNSPECIFIED); 

 

   MeasureSpec.EXACTLY | itemWidth? 

 

  3. View.setMeasuredDimension() 与 ViewGroup.measureChildren()的区别?




四、 资料


官方资料:Custom Components



http://developer.android.com/guide/topics/ui/custom-components.html



计算控件尺寸




MeasureSpec介绍  ( 如何计算size和mode )




重写onMeasure典型例子:

http://www.blogjava.net/liuyanbo/archive/2012/03/15/371969.html






提高:


自定义view改成addview多个,每个layout参数不同


各种模式画图比较





    本篇对覆写onMeausre有所了解,但是知道进行测量并不能显示视图,还需要进行onLayout操作,可以查看此文章 《覆写onLayout进行layout,含自定义ViewGroup例子》