<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;">package com.example.clipdrawabledemo;
import android.content.Context;
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.view.MotionEvent;
import android.view.View;
/*
* 本view实现了一个简单的画图板的功能,当用户在触摸屏上移动时,即可在屏幕上绘制任意的图形
* 实现手绘其实是一种假象:表面上看起来可以随用户可任意的画曲线,实际上依然利用的是Canvas的DrawLine方法画直线
* 每条直线都是从上一次拖动事件发生点画到本次拖动时间发生点,当用户在触摸屏上移动时,两次拖动事件的距离很小,多条极短的直线连接起来
* 肉眼看起来就像是曲线,懂微积分的同学应该清楚
* 需要指出的是:如果程序每次都只是从上一次拖动事件的发生点绘一条直线到本次事件的发生点,那么用户前面绘制的将会
* 丢失,为了保留前面绘制的图形,要采用双缓冲技术,
* <span style="color:#ff6666;">所谓双缓冲技术</span>:当程序在指定View上进行绘制时,程序并不直接绘制到该View上,而是先绘制到
* 一个内存中的Bitmap图片(这就是缓冲)上,等到内存上的Bitmap绘制完成后,在一次性的绘制到View组件上
*/
public class DrawView extends View {
float preX;// 前一个点的x坐标
float preY;// 前一个点的y坐标
private Path path;// 路径
private Paint paint = null;// 画笔
final int VIEW_WITH = 480;// 画面宽度
final int VIEW_HEIGHT = 800;// 画面高度
private Bitmap cacheBitmap = null;// 定义内存中的图片,该图片作为缓冲区
private Canvas cacheCanvas = null;// Bitmap上的Canvas的对象
public DrawView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
// 创建一个和屏相适应的缓冲区
cacheBitmap = Bitmap.createBitmap(VIEW_WITH, VIEW_HEIGHT,
Config.ARGB_8888);
cacheCanvas = new Canvas();
path = new Path();
// 设置cacheCanvas绘制到内存中的cacheBitmap
cacheCanvas.setBitmap(cacheBitmap);
setPaint();
}
private void setPaint(){
paint = new Paint(Paint.DITHER_FLAG);// 防抖动,与setDither相对应
paint.setColor(Color.GREEN);// 设置画笔颜色
paint.setStyle(Paint.Style.STROKE);// 设置样式为空心
paint.setStrokeWidth(10);// 设置宽度
paint.setAntiAlias(true);// 反锯齿
paint.setDither(true);// 防抖
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
//setPaint();
System.out.println("onTouchEvent---"+"x="+x+";y="+y);
// TODO Auto-generated method stub
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
System.out.println("ACTION_DOWN");
path.moveTo(x, y);
preX = x;
preY = y;
break;
case MotionEvent.ACTION_MOVE:
System.out.println("ACTION_MOVE");
//该方法的实现是当我们不仅仅是画一条线甚至是画弧线时会形成平滑的曲线,该曲线又称为"贝塞尔曲线"
//这里也可是使用path.lineTo(x, y);
path.quadTo(preX, preY, x, y);
preX = x;
preY = y;
break;
case MotionEvent.ACTION_UP:
System.out.println("ACTION_UP");
cacheCanvas.drawPath(path, paint);
//清除画笔设置
//paint.reset();
break;
}
invalidate();//刷新View
return true;// 返回true表示事件响应完成,不会扩展
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
System.out.println("onDraw");
Paint Bitpaint = new Paint();
canvas.drawBitmap(cacheBitmap, 0, 0, Bitpaint);// 将cacheBitmap绘制到该View上
canvas.drawPath(path, paint);// 沿着path绘制
}
}
</span></span>