在view加载完之后android就开始进行view的绘制了,在view的绘制过程都必须经历三个最主要的过程,也就是measure、layout和draw,接下来进行逐个分析。
1、measure过程
measure过程主要是对view的宽高进行测量,获取view的大小,在view中对应的方法是onMeasure方法,如下:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
MeasureSpec里面封装了两个信息,一个是宽高,另一个是模式。
- int width = MeasureSpec.getSize(widthMeasureSpec);// 布局的宽度
- int height = MeasureSpec.getSize(heightMeasureSpec);// 布局的高度
- int widthMode = MeasureSpec.getMode(widthMeasureSpec);// 宽度的模式
- int heightMode = MeasureSpec.getMode(heightMeasureSpec);// 高度的模式
模式分为三种:
- MeasureSpec.AT_MOST; 至多 wrap_content
- MeasureSpec.EXACTLY; 确定模式 布局文件中写死dp或者match_parent
- MeasureSpec.UNSPECIFIED;未确定的模式
重新设置宽高模式:
- heightMeasureSpec = MeasureSpec.makeMeasureSpec(height,MeasureSpec.EXACTLY);
- widthMeasureSpec = MeasureSpec.makeMeasureSpec(width,MeasureSpec.EXACTLY);
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
设置控件的活动范围,指定在屏幕的大小:
- setMeasuredDimension(width,height);
手动测量控件的大小:
- measure(int, int);
2、layout过程
layout主要是设置绘制的位置,对应view中的方法是onLayout,这个方法中可以获取到被绘制的view的宽高,在view给其孩子设置尺寸和位置时被调用。子view,包括孩子在内,必须重写onLayout(boolean, int, int, int, int)方法,并且调用各自的layout(int, int, int, int)方法。
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
这个方法的参数是相对于父view的位置。
3、draw过程
draw是绘制的方法,在view中对应的是 onDraw方法,在这个方法里面执行view的绘制,可以绘制常见的形状,文字,路径、贝塞尔曲线等等。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
Canvas是一个绘制的类,是一个绘制形状的类包含了很多形状,这样就可以直接绘制了,一般的绘制步骤为:创建画笔,为画笔设置属性,绘制三步。
这三个方法是view绘制中比较核心的方法,除了这两个之外还有两个方法也比较常用分别是onFinishInflate,onSizeChanged如下:
- onFinishInflate是在xml的布局加载完成之后回调,通常再次方法里面进行findviewbyid进行初始化。
- onSizeChanged是当控件的尺寸发生变化的时候调用,通常在此方法里面进行手动测量view的宽高
以上就是view的加载机制中涉及到的常用知识,在自定义控件中就是灵活的使用这些方面的知识进行灵活的运用。除了这些在自定义控件中还需要用到事件的处理机制,手势识别,ViewDragHelper等知识点综合运行,才能实现一个完美的效果。