覆写onMeaure进行measure操作

来源:互联网 发布:手机淘宝查询消费总额 编辑:程序博客网 时间:2024/05/27 06:15
    android在屏幕上绘制视图3步: measure测量、layout布局、draw绘制。
     这里主要介绍第一步measure,measure是view大小计算的过程。先来一个自定义View的例子,演示如何覆写onMeasure方法

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


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


1. 覆写onMeasure
[plain] view plaincopyprint?
  1. @Override   
  2. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {   
  3.   
  4. }  


2. 分别计算出宽高,后面解释使用的方法的作用
[plain] view plaincopyprint?
  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 plaincopyprint?
  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_contentparent view 为child view指定最大的值,child view可以在范围内设置EXACTLY准确的fill_parent,精确值(例如50dip)parent view为child view指定固定大小


三、 疑惑

例子总只写了一个view,在onMeasure中添加log获知此方法执行2次? 在ADT 20.3中同样的代码onMeasure执行4次?不是应该只执行一次吗?
我整明白了,当new ViewGroup()的时候,通过getWidth()和getHeight()(在构造方法里打log),得到的值首先是0,0,然后通过调用onMeasure()和onLayout()方法,会对这个view测量大小,这个时候view的宽高就发生了改变,这个时候又会重新调用一次onMeasure和onLayout方法(当view发生改变的时候,这两个方法会被调用),这时候你通过getWidth和getHeight方法就可以看到被测量之后的宽高了。这就是会调用两次的原因。

如果父视图的子视图的个数为0,就会执行一次。否则就会执行多次。因为开始时父试图中是没有子试图的。但是当你从xml文件中加载子试图或者在java代码中添加子试图时,父试图的状态会发生变化,这个变化会引起onlayout甚至是onmeasure。




四、 资料
官方资料:Custom Components
http://developer.android.com/guide/topics/ui/custom-components.html

计算控件尺寸
http://www.cnblogs.com/xirihanlin/archive/2009/07/23/1529238.html

MeasureSpec介绍  ( 如何计算size和mode )
http://blog.csdn.net/whyrjj3/article/details/7927585

重写onMeasure典型例子:
http://www.blogjava.net/liuyanbo/archive/2012/03/15/371969.html




提高:
自定义view改成addview多个,每个layout参数不同
各种模式画图比较

原创粉丝点击