现实生活中,如果我们要去画一个图形,就必须知道它的位置和大小。
Android系统在绘制View前,也必须对View进行测量,这个过程在onMeasure()方法中进行。
MeaSureSpec
Android 提供的测量View的一个类,是一个32位int值,其中高2位为测量模式,低30位为测量大小(size)。
测量模式可分为3类:
- EXACTLY
精确值模式:将layout_width或layout_height属性指定为具体数值(30dp)或者match_parent - AT_MOST
最大值模式:将layout_width或layout_height指定为wrap_content。 - UNSPECIFIED
View想多大就多大。通常在自定义View才会使用。
注意:
View的默认哦那Measure()只支持EXACTLY,
如果让自定的view支持wrap_content,必须重写onMeasure()来指定wrap_content大小。
简单示例:
public class MeasuredView extends View {
public MeasuredView(Context context) {
super(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// 调用父类的onMeasure()
super.onMeasure(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
// 或者直接调用父类的setMeasuredDimension(),因为父类的onMeasure()最终调用了setMeasuredDimension()
// setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
}
/**
* 测量View的width
* @param measureSpec MeasureSpec对象
* @return View的width
*/
private int measureWidth(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
} else {
result = 200;
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return result;
}
/**
* 测量View的height
* @param measureSpec MeasureSpec对象
* @return View的height
*/
private int measureHeight(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
} else {
result = 200;
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return result;
}
}
View的绘制
2D绘图必备利器——Canvas
获取Canvas对象的方式:
a. 由方法中的参数传入,例如,View的onDraw()中有一个参数就是Canvas对象
b. 通过构造方法构造,即:Canvas canvas = new Canvas(bitmap),在Canvas的构造方法传入一个Bitmap对象,即可获取一个Canvas对象。通过传入Bitmap对象构造Canvas对象的过程称为“画布的装载”,传入的Bitmap对象承载了多有绘制在Canvas上的像素信息,调用Canvas.drawXXX方法(如:Canvas.drawBitmap(bitmap, 0, 0, null))都将发生在该Bitmap对象上。
利用Canvas绘图
a. 通过Canvas.drwaXXX进行绘制操作将直接作用于Bitmap对象,当再次刷新View的时候,我们将会被绘制的Bitmap对象发生了改变;
b. 利用Canvas和Paint进行绘图;
c. 不管多么复杂、精美的空间,都可以被拆分为一个个小的图形单元,我们只要找到这些图形单元,就可以将控件绘制出来。
参考:Android群英传
Android视图控件架构分析之View、ViewGroup
网友评论