Android开发笔记(十三)视图绘制的几个方法

来源:互联网 发布:plc触摸屏编程实例 编辑:程序博客网 时间:2024/05/16 09:29

三个可进行绘制的方法

在自定义视图中,有三个函数可以重写用于界面绘制,在视图创建过程中,三个函数的执行顺序依次是:onLayout、onDraw、dispatchDraw。
1、onLayout(boolean changed, int left, int top, int right, int bottom) : 
onLayout用于定位该视图在上级视图中的位置,从其参数中就可以看出来。由于该函数没有画布,因此只适合绘制现成的视图控件。
2、onDraw(Canvas canvas) : 
自定义控件一般是重写onDraw方法,在画布中绘制各种图形。
3、dispatchDraw(Canvas canvas) : 
dispatchDraw与onDraw的区别在于:onDraw在绘制下级视图之前,而dispatchDraw在绘制下级视图之后,所以如果不想自己的绘图被下级视图覆盖的话,就要在dispatchDraw中进行绘制操作。为方便记忆,只要是从ViewGroup衍生出的视图,都用dispatchDraw,其他小控件都用onDraw。


Canvas画布的使用

Canvas是Android提供的图形操作类,Canvas的使用不难,多练习几次就熟练了。下面列出Canvas的常用方法:


划定可绘制的区域(裁剪区域)

虽然本视图内的所有区域都是可以绘制的,但是有时候我们还是只想在某个圆形区域或者矩形区域内部画画,那么在绘制之前就得指定允许绘制的区域大小
clipPath : 裁剪不规则曲线区域
clipRect : 裁剪矩形区域
clipRegion : 裁剪一块组合区域


在区域内部绘制图形

drawArc : 绘制扇形
drawBitmap : 绘制图像
drawCircle : 绘制圆形
drawLine : 绘制直线
drawOval : 绘制椭圆
drawPath : 绘制路径,即不规则曲线
drawPoint : 绘制点
drawRect : 绘制矩形
drawRoundRect : 绘制圆角矩形
drawText : 绘制文本


移动整个画布

rotate : 旋转画布
scale : 缩放画布
translate : 平移画布


存取画布的状态

Canvas的不同绘制操作会互相影响,比如说我们想对整个画布做旋转,除了某个直线(即该直线保持不动),如果没有状态机制,那么该直线也只能跟着旋转。有了状态机制,我们就可以在绘制该直线前保存画布状态(保存旋转操作),然后画直线,最后再恢复画布状态。这样在save-restore代码之间绘制的任何图形,都不会收到save-restore代码以外其他图形操作的影响。
save : 保存画布状态
restore : 恢复画布状态



画笔Paint的使用

在上述绘制图形函数当中,都需要指定Paint,Paint上定义了画笔的颜色、样式、粗细、阴影、下划线等等。Paint的常用操作包括:
setAntiAlias : 设置是否使用抗锯齿功能,主要用于画圆圈等曲线
setColor : 设置画笔的颜色
setShader : 设置画笔的渐变效果
setShadowLayer :  设置画笔的阴影
setStyle : 设置画笔的样式(线条还是填充)
setStrokeWidth : 设置线条的粗细
setUnderlineText : 设置文本的下划线
setStrikeThruText : 设置文本的删除线


代码示例

下面是一个自定义签名控件的代码示例:
import java.util.ArrayList;import com.example.exmcustom.R;import android.annotation.SuppressLint;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.Bitmap.Config;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;public class SignatureView extends View {private static final String TAG = "SignatureView";private Paint paint;private Canvas cacheCanvas;private Bitmap cachebBitmap;private Path path;private int paint_color = Color.BLACK;private int stroke_width = 3;private PathPosition pos = new PathPosition();private ArrayList<PathPosition> pathArray = new ArrayList<PathPosition>();private int mWidth=0, mHeight=0;public SignatureView(Context context,AttributeSet attrs) {super(context, attrs);if (attrs != null) {        TypedArray attrArray=getContext().obtainStyledAttributes( attrs, R.styleable.SignatureView);        paint_color = attrArray.getColor(R.styleable.SignatureView_paint_color, Color.BLACK);        stroke_width = attrArray.getInt(R.styleable.SignatureView_stroke_width, 3);        attrArray.recycle();}}public SignatureView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);if (attrs != null) {        TypedArray attrArray=getContext().obtainStyledAttributes( attrs, R.styleable.SignatureView);        paint_color = attrArray.getColor(R.styleable.SignatureView_paint_color, Color.BLACK);        stroke_width = attrArray.getColor(R.styleable.SignatureView_stroke_width, 3);        attrArray.recycle();}}public SignatureView(Context context) {super(context);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);mWidth = this.getMeasuredWidth();mHeight = this.getMeasuredHeight();Log.d(TAG, "onMeasure width="+mWidth+",height="+mHeight);init(mWidth, mHeight);}public SignatureView(Context context, int width, int height) {super(context);init(width, height);}public int getPaintColor() {return paint_color;}public void setPaintColor(int paint_color) {this.paint_color = paint_color;}public int getStrokeWidth() {return stroke_width;}public void setStrokeWidth(int stroke_width) {this.stroke_width = stroke_width;}public Bitmap getCachebBitmap() {return getDrawingCache();}private void init(int width, int height) {paint = new Paint();paint.setAntiAlias(true);paint.setStrokeWidth(stroke_width);paint.setStyle(Paint.Style.STROKE);paint.setColor(paint_color);path = new Path();setDrawingCacheEnabled(true);cachebBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);cacheCanvas = new Canvas(cachebBitmap);cacheCanvas.drawColor(Color.WHITE);}public void clear() {if (cacheCanvas != null) {pathArray.clear();cacheCanvas.drawRGB(255, 255, 255);invalidate();}}public void revoke() {if (pathArray.size() > 0) {pathArray.remove(pathArray.size()-1);cacheCanvas.drawRGB(255, 255, 255);for (int i=0; i<pathArray.size(); i++) {Path posPath = new Path();posPath.moveTo(pathArray.get(i).firstX, pathArray.get(i).firstY);posPath.quadTo(pathArray.get(i).firstX, pathArray.get(i).firstY, pathArray.get(i).nextX, pathArray.get(i).nextY);cacheCanvas.drawPath(posPath, paint);}invalidate();}}@SuppressLint("DrawAllocation")@Overrideprotected void onDraw(Canvas canvas) {canvas.drawBitmap(cachebBitmap, 0, 0, null);canvas.drawPath(path, paint); //这个是需要的,最近一次的路径保存在这里}private float cur_x, cur_y;@SuppressLint("ClickableViewAccessibility")@Overridepublic boolean onTouchEvent(MotionEvent event) {float x = event.getX();float y = event.getY();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:cur_x = x;cur_y = y;path.moveTo(cur_x, cur_y);pos.firstX = cur_x;pos.firstY = cur_y;break;case MotionEvent.ACTION_MOVE:path.quadTo(cur_x, cur_y, x, y);cur_x = x;cur_y = y;pos.nextX = cur_x;pos.nextY = cur_y;pathArray.add(pos);pos = new PathPosition();pos.firstX = cur_x;pos.firstY = cur_y;break;case MotionEvent.ACTION_UP:cacheCanvas.drawPath(path, paint);path.reset();break;}invalidate();return true;}}




点此查看Android开发笔记的完整目录

0 0
原创粉丝点击