首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > 移动开发 >

View兑现涂鸦、撤销以及重做功能

2012-07-20 
View实现涂鸦、撤销以及重做功能eoe上既然看见了,就备份一下,少许更改了部分代码:import java.io.Fileimpo

View实现涂鸦、撤销以及重做功能
eoe上既然看见了,就备份一下,少许更改了部分代码:

import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Path;import android.graphics.Bitmap.CompressFormat;import android.os.Environment;import android.view.MotionEvent;import android.view.View;/** * View实现涂鸦、撤销以及重做功能 */public class TuyaView extends View {private Bitmap mBitmap;private Canvas mCanvas;private Path mPath;private Paint mBitmapPaint;// 画布的画笔private Paint mPaint;// 真实的画笔private float mX, mY;// 临时点坐标private static final float TOUCH_TOLERANCE = 4;// 保存Path路径的集合,用List集合来模拟栈private static List<DrawPath> savePath;// 记录Path路径的对象private DrawPath dp;private int screenWidth, screenHeight;private class DrawPath {public Path path;// 路径public Paint paint;// 画笔}public TuyaView(Context context, int w, int h) {super(context);screenWidth = w;screenHeight = h;mBitmap = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888);// 保存一次一次绘制出来的图形mCanvas = new Canvas(mBitmap);mBitmapPaint = new Paint(Paint.DITHER_FLAG);mPaint = new Paint();mPaint.setAntiAlias(true);mPaint.setStyle(Paint.Style.STROKE);mPaint.setStrokeJoin(Paint.Join.ROUND);// 设置外边缘mPaint.setStrokeCap(Paint.Cap.ROUND);// 形状mPaint.setStrokeWidth(5);// 画笔宽度savePath = new ArrayList<DrawPath>();}@Overridepublic void onDraw(Canvas canvas) {canvas.drawColor(0xFFAAAAAA);// 将前面已经画过得显示出来canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);if (mPath != null) {// 实时的显示canvas.drawPath(mPath, mPaint);}}private void touch_start(float x, float y) {mPath.moveTo(x, y);mX = x;mY = y;}private void touch_move(float x, float y) {float dx = Math.abs(x - mX);float dy = Math.abs(mY - y);if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {// 从x1,y1到x2,y2画一条贝塞尔曲线,更平滑(直接用mPath.lineTo也是可以的)mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);mX = x;mY = y;}}private void touch_up() {mPath.lineTo(mX, mY);mCanvas.drawPath(mPath, mPaint);//将一条完整的路径保存下来(相当于入栈操作)savePath.add(dp);mPath = null;// 重新置空}/** * 撤销的核心思想就是将画布清空, * 将保存下来的Path路径最后一个移除掉, * 重新将路径画在画布上面。 */public void undo() {if (savePath != null && savePath.size() > 0) {savePath.remove(savePath.size() - 1);redrawOnBitmap();}}/** * 重做 */public void redo(){if (savePath != null && savePath.size() > 0) {savePath.clear();redrawOnBitmap();}}private void redrawOnBitmap(){mBitmap = Bitmap.createBitmap(screenWidth, screenHeight,Bitmap.Config.ARGB_8888);mCanvas.setBitmap(mBitmap);// 重新设置画布,相当于清空画布 Iterator<DrawPath> iter = savePath.iterator();while (iter.hasNext()) {DrawPath drawPath = iter.next();mCanvas.drawPath(drawPath.path, drawPath.paint);}invalidate();// 刷新}@Overridepublic boolean onTouchEvent(MotionEvent event) {float x = event.getX();float y = event.getY();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:// 每次down下去重新new一个PathmPath = new Path();//每一次记录的路径对象是不一样的dp = new DrawPath();dp.path = mPath;dp.paint = mPaint;touch_start(x, y);invalidate();break;case MotionEvent.ACTION_MOVE:touch_move(x, y);invalidate();break;case MotionEvent.ACTION_UP:touch_up();invalidate();break;}return true;}public void saveToSDCard(){String fileUrl = Environment.getExternalStorageDirectory().toString() + "/android/data/test.png";try {FileOutputStream fos = new FileOutputStream(new File(fileUrl));mBitmap.compress(CompressFormat.PNG, 100, fos);fos.flush();fos.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}


import android.app.Activity;import android.os.Bundle;import android.util.DisplayMetrics;import android.util.Log;import android.view.KeyEvent;public class TuyaActivity extends Activity {private TuyaView tuyaView = null;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);DisplayMetrics dm = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(dm);tuyaView = new TuyaView(this, dm.widthPixels, dm.heightPixels);setContentView(tuyaView);}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_BACK) {// 返回键tuyaView.undo();return true;}else if(keyCode == KeyEvent.KEYCODE_MENU){//MENUtuyaView.redo();return true;}return super.onKeyDown(keyCode, event);}}



热点排行