这里主要介绍第一步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例子》