手写功能,撤回上一步,清空,保存 功能

来源:互联网 发布:α β 滤波算法matlab 编辑:程序博客网 时间:2024/06/11 19:35
package com.example.handwriting;


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
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.view.MotionEvent;
import android.view.View;


public class DrawView extends View{

private Paint mPaint;//画笔
private Canvas mCanvas;//画布
private Path mPath; //画笔路径
private Bitmap mBitmap;//缓存图片
private int width,height;//图片宽度。高度
private float Xdown,Ydown;//手指坐标
private boolean isDrawing = false;//是否正在绘制
// 保存Path路径的集合,用List集合来模拟栈
private static List<DrawPath> savePath;
// 记录Path路径的对象
private DrawPath dp;
private class DrawPath {
 public Path path;// 路径
 public Paint paint;// 画笔
}

public DrawView(Context context, int width, int height) {//构造
super(context);
this.width = width;
this.height = height;
initWedgits();
}

private void initWedgits() {
mPaint = new Paint(Color.RED);
mPaint.setAntiAlias(true);//抗锯齿
mPaint.setStrokeWidth(3);
mPaint.setDither(true);
// 设置样式
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setColor(Color.RED);// 画笔颜色
mPath = new Path();
// 创建空缓存图片
mBitmap  = Bitmap.createBitmap(width, height, Config.ARGB_8888);
mCanvas= new Canvas(mBitmap);// 把画布内容画到空缓存图片上
savePath = new ArrayList<DrawPath>();//撤销1
}


@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
canvas.drawColor(Color.YELLOW);
canvas.drawBitmap(mBitmap, 0,0, mPaint);
if (mPath != null) {
  canvas.drawPath(mPath, mPaint);  // 实时的显示
}
}




@Override
public boolean onTouchEvent(MotionEvent event) {
final float x = event.getX();// 记录手指摁下屏幕时的Y坐标
final float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 手指摁下时清空之前的设置
//path.reset();
mPath = new Path();
dp = new DrawPath();
dp.path = mPath;
   dp.paint = mPaint;
// 设置路径起始点
   mPath.moveTo(x, y);
Xdown = x;
Ydown = y;
isDrawing = true;
invalidate();
break;
case MotionEvent.ACTION_MOVE:
// 移动下一点
mPath.quadTo(Xdown, Ydown, x, y);
// 重新设置起点
Xdown = x;
Ydown = y;
isDrawing = true;
break;
case MotionEvent.ACTION_UP:
mPath.lineTo(Xdown, Ydown);
mCanvas.drawPath(mPath, mPaint);// 手指抬起时绘制路径
//mPath.reset();// 路径重置//罪魁祸首
mPath = null;// 重新置空
isDrawing = false;
savePath.add(dp);
//撤销操作以上不成功
/*mPath.lineTo(Xdown, Ydown);
mCanvas.drawPath(mPath, mPaint);
//将一条完整的路径保存下来(相当于入栈操作)
savePath.add(dp);
mPath = null;// 重新置空
isDrawing = false;*/
invalidate();
break;
default:
break;
}
// 刷新界面
invalidate();//系统函数
return true;
}


/**
* 返回绘画状态
* @return【true:正在绘制】【false:绘制完成】
*/
public boolean getDrawState() {
return isDrawing;
}


/**
* 返回Bitmap
* @return 返回绘制的图片
*/
public Bitmap getBitmap() {
return mBitmap;
}

/**
* 清除所有图片操作
*/
public void clear() {
initWedgits();
invalidate();//刷新
}





/**
* 撤销上一步操作
*/
public void undo() {
// TODO Auto-generated method stub
mBitmap  = Bitmap.createBitmap(width, height, Config.ARGB_8888);//111
mCanvas= new Canvas(mBitmap);// 清空画布
if (savePath != null && savePath.size() > 0) {


  // 移除最后一个path,相当于出栈操作
  savePath.remove(savePath.size() - 1);
  Iterator<DrawPath> iter = savePath.iterator();
  while (iter.hasNext()) {
   DrawPath drawPath = iter.next();
   mCanvas.drawPath(drawPath.path, drawPath.paint);
  }
  invalidate();// 刷新
 
}
}



/*DrawView的代码注释都很清晰,我还是大致说下DrawView的执行逻辑吧,
DrawView继承了View也就是说具有了View的所有功能,
要实现图片绘制就要实现onDraw()方法,要实现对手指在屏幕上的轨迹绘制就需要获取轨迹坐标,
所以需要重写onTouchEvent()放法,重点在onTouchEvent()方法中。当手指摁下时我们绘制起点,
但是在绘制起点前需要先调用path.reset()方法,防止path进行二次重绘,
path的moveTo方法就是来绘制当前触摸事件的起点,摁下完成之后调用inValidate()方法进行界面刷新。
当手指移动时调用path.quadTo()方法,这个方法就是追加的意思,把新坐标点追加到path中,
手指移动之后再调用inValidate()方法进行界面刷新,最后当手指抬起时,
把在当前事件周期内的轨迹绘制到画板cacheCanvas上,最后再调用inValidate()方法进行界面刷新,
因此一次的手指移动轨迹就绘制完成,当要进行下一次的绘制,就是重复以上操作了...
*/


}
1 0
原创粉丝点击