当前位置:操作系统 > 安卓/Android >>

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

Java代码 
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>(); 
    } 
 
    @Override 
    public 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(); 
        } 
    } 
    /**
     * 重做 www.zzzyk.com
     */ 
    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(); 
  &nb
补充:移动开发 , Android ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,