2016-05-10 4 views
2

Ich benutze obigen Code für rückgängig machen, aber Leinwand kann nicht durch den Aufruf dieser Methode aktualisieren. Ich habe erstellt DrawingView Klasse für Skizze Funktion i Undo wie für jede Funktionalität nur tun müssen, 1. smooth 2.Rectangle 3.Circle 4.Straight Linie usw.Innerhalb der Leinwand für Bildskizze rückgängig machen

public class DrawingView extends View { 

    protected Path mPath = new Path(); 
    public static Paint mPaint; 
    protected Bitmap mBitmap; 
    public static Canvas mCanvas; 
    public int TOUCH_TOLERANCE = 5; 
    public static int lineThickness = 5; 
    public static int mCurrentShape; 
    public boolean isDrawing = false; 
    float mx,my,mStartX,mStartY; 

    private int stateToSave; 

    public static Paint mPaintErase = new Paint(); 
    protected Path mPathErase = new Path(); 

    private ArrayList<Path> paths = new ArrayList<Path>(); 
    private ArrayList<Path> undonePaths = new ArrayList<Path>(); 

    public DrawingView(Context context) { 
     super(context); 
     init(); 
     EraseLine(); 
    } 

    public DrawingView(Context context,AttributeSet attrs) 
    { 
     super(context, attrs); 
     init(); 
     EraseLine(); 
    } 



    /** 
    * Create Path from Event. 
    * @param event 
    * @return 
    */ 
    private Path createPath(MotionEvent event) { 
     Path path = new Path(); 

     // Save for ACTION_MOVE 
     this.mStartX = event.getX(); 
     this.mStartY = event.getY(); 

     path.moveTo(this.mStartX, this.mStartY); 

     return path; 
    } 


    protected void init() 
    { 
     mPaint = new Paint(Paint.DITHER_FLAG); 
     mPaint.setAntiAlias(true); 
     mPaint.setDither(true); 
     mPaint.setColor(getContext().getResources().getColor(R.color.colorYellow)); 
     mPaint.setStyle(Paint.Style.STROKE); 
     mPaint.setStrokeJoin(Paint.Join.ROUND); 
     mPaint.setStrokeCap(Paint.Cap.ROUND); 
     mPaint.setStrokeWidth(lineThickness); 

     mPath = new Path(); 
     paths.add(mPath); 
    } 

    public Bitmap getBitmap() 
    { 
     this.setDrawingCacheEnabled(true); 
     this.buildDrawingCache(); 
     Bitmap bmp = Bitmap.createBitmap(this.getDrawingCache()); 
     this.setDrawingCacheEnabled(false); 

     return bmp; 
    } 

    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
     super.onSizeChanged(w, h, oldw, oldh); 
     mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); 
     mCanvas = new Canvas(mBitmap); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) 
    { 
     mx = event.getX(); 
     my = event.getY(); 

     switch (mCurrentShape) 
     { 
      case 1: 
       onTouchEventSmoothLine(event); 
       break; 

      case 2: 

       onTouchEventErase(event); 
       break; 

      case 3: 

       onTouchEventLine(event); 
       break; 

      case 4: 

       onTouchEventCircle(event); 
       break; 

      case 5: 

       onTouchEventRectangle(event); 
       break; 

      case 6: 

       break; 

      default: 
       break; 
     } 
     return true; 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 

     canvas.drawBitmap(mBitmap, 0, 0, mPaint); 

     if (isDrawing) 
     { 
      switch (mCurrentShape) 
      { 
       case 1: 

        break; 

       case 2: 

       // EraseLine(); 
        break; 

       case 3: 

        onDrawLine(canvas); 
        break; 

       case 4: 

        onDrawCircle(canvas); 
        break; 

       case 5: 

        onDrawRectangle(canvas); 
        break; 

       case 6: 

        onDrawSmoothLine(canvas); 
        break; 

       default: 
        break; 
      } 
     } 
    } 

    //------------------------------------------------------------------ 
    // Rectangle 
    //------------------------------------------------------------------ 
    private void onTouchEventRectangle(MotionEvent event) { 

     switch (event.getAction()) 
     { 
      case MotionEvent.ACTION_DOWN: 

       isDrawing = true; 
       mStartX = mx; 
       mStartY = my; 
       invalidate(); 
       break; 

      case MotionEvent.ACTION_MOVE: 

       invalidate(); 
       break; 

      case MotionEvent.ACTION_UP: 

       isDrawing = false; 
       drawRectangle(mCanvas,mPaint); 
       invalidate(); 
       break; 
     } 
    } 

    private void onDrawRectangle(Canvas canvas) { 
     drawRectangle(canvas, mPaint); 
    } 

    private void drawRectangle(Canvas canvas,Paint paint){ 
     float right = mStartX > mx ? mStartX : mx; 
     float left = mStartX > mx ? mx : mStartX; 
     float bottom = mStartY > my ? mStartY : my; 
     float top = mStartY > my ? my : mStartY; 
     canvas.drawRect(left, top, right, bottom, paint); 
    } 

    //------------------------------------------------------------------ 
    // Circle 
    //------------------------------------------------------------------ 
    private void onDrawCircle(Canvas canvas) { 
     canvas.drawCircle(mStartX, mStartY, calculateRadius(mStartX, mStartY, mx, my), mPaint); 
    } 

    private void onTouchEventCircle(MotionEvent event) 
    { 
     switch (event.getAction()) 
     { 
      case MotionEvent.ACTION_DOWN: 
       isDrawing = true; 
       mStartX = mx; 
       mStartY = my; 
       invalidate(); 
       break; 

      case MotionEvent.ACTION_MOVE: 
       invalidate(); 
       break; 

      case MotionEvent.ACTION_UP: 
       isDrawing = false; 
       mCanvas.drawCircle(mStartX, mStartY, 
         calculateRadius(mStartX,mStartY,mx,my),mPaint); 
       invalidate(); 
       break; 

      default: 
       break; 
     } 
    } 

    /** 
    * @return 
    */ 
    protected float calculateRadius(float x1, float y1, float x2, float y2) { 

     return (float) Math.sqrt(
       Math.pow(x1 - x2, 2) + 
         Math.pow(y1 - y2, 2) 
     ); 
    } 

    //------------------------------------------------------------------ 
    // Line 
    //------------------------------------------------------------------ 
    private void onDrawLine(Canvas canvas) { 

     float dx = Math.abs(mx - mStartX); 
     float dy = Math.abs(my - mStartY); 
     if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) 
     { 
      canvas.drawLine(mStartX, mStartY, mx, my, mPaint); 
     } 
    } 

    private void onTouchEventLine(MotionEvent event) { 

     switch (event.getAction()) 
     { 
      case MotionEvent.ACTION_DOWN: 
       isDrawing = true; 
       mStartX = mx; 
       mStartY = my; 
       invalidate(); 
       break; 
      case MotionEvent.ACTION_MOVE: 
       invalidate(); 
       break; 
      case MotionEvent.ACTION_UP: 
       isDrawing = false; 
       mCanvas.drawLine(mStartX, mStartY, mx, my, mPaint); 
       invalidate(); 
       break; 
     } 
    } 

    //------------------------------------------------------------------ 
    // Smooth Line 
    //------------------------------------------------------------------ 
    private void onDrawSmoothLine(Canvas canvas) 
    { 
     for (Path p : paths) 
     { 
      canvas.drawPath(p, mPaint); 
     } 
    } 

    private void onTouchEventSmoothLine(MotionEvent event) 
    { 

     switch (event.getAction()) 
     { 
      case MotionEvent.ACTION_DOWN: 
       isDrawing = true; 
       mStartX = mx; 
       mStartY = my; 

       mPath.reset(); 
       mPath.moveTo(mx, my); 

       invalidate(); 
       break; 
      case MotionEvent.ACTION_MOVE: 

       float dx = Math.abs(mx - mStartX); 
       float dy = Math.abs(my - mStartY); 
       if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { 
        mPath.quadTo(mStartX, mStartY, (mx + mStartX)/2, (my + mStartY)/2); 
        mStartX = mx; 
        mStartY = my; 
       } 
       mCanvas.drawPath(mPath, mPaint); 
       invalidate(); 
       break; 

      case MotionEvent.ACTION_UP: 
       isDrawing = false; 
       mPath.lineTo(mStartX, mStartY); 
       mCanvas.drawPath(mPath, mPaint); 
       mPath.reset(); 
       paths.add(mPath); 
       invalidate(); 
       break; 
     } 
    } 

    //------------------------------------------------------------------ 
    // Erase Line 
    //------------------------------------------------------------------ 
    public void EraseLine() 
    { 
     mPaintErase.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 
     mPaintErase.setColor(Color.TRANSPARENT); 
     mPaintErase.setAntiAlias(true); 
     mPaintErase.setDither(true); 
     mPaintErase.setStyle(Paint.Style.STROKE); 
     mPaintErase.setStrokeJoin(Paint.Join.ROUND); 
     mPaintErase.setStrokeCap(Paint.Cap.ROUND); 
     mPaintErase.setStrokeWidth(lineThickness); 
    } 

    private void onTouchEventErase(MotionEvent event) 
    { 
     switch (event.getAction()) 
     { 
      case MotionEvent.ACTION_DOWN: 

       isDrawing = true; 
       mStartX = mx; 
       mStartY = my; 
       mPathErase.reset(); 
       mPathErase.moveTo(mx, my); 
       invalidate(); 
       break; 

      case MotionEvent.ACTION_MOVE: 

       float dx = Math.abs(mx - mStartX); 
       float dy = Math.abs(my - mStartY); 
       if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { 
        mPathErase.quadTo(mStartX, mStartY, (mx + mStartX)/2, (my + mStartY)/2); 
        mStartX = mx; 
        mStartY = my; 
       } 
       mCanvas.drawPath(mPathErase, mPaintErase); 
       invalidate(); 
       break; 

      case MotionEvent.ACTION_UP: 

       isDrawing = false; 
       mPathErase.lineTo(mStartX, mStartY); 
       mCanvas.drawPath(mPathErase, mPaintErase); 
       mPathErase.reset(); 
       invalidate(); 
       break; 
     } 
    } 

    /** 
    * Undo functionality. 
    */ 
    public void onClickUndo() 
    { 
     if (paths.size()>0) 
     { 
      paths.remove(paths.size()-1); 
      invalidate(); 
     } 
     else 
     { 
      Toast.makeText(getContext().getApplicationContext(),"Undo not found.",Toast.LENGTH_SHORT).show(); 
     } 
     //toast the user 
    } 

    @Override 
    public Parcelable onSaveInstanceState() { 
     //begin boilerplate code that allows parent classes to save state 
     Parcelable superState = super.onSaveInstanceState(); 

     SavedState ss = new SavedState(superState); 
     //end 

     ss.stateToSave = this.stateToSave; 

     return ss; 
    } 

    @Override 
    public void onRestoreInstanceState(Parcelable state) { 
     //begin boilerplate code so parent classes can restore state 
     if(!(state instanceof SavedState)) { 
      super.onRestoreInstanceState(state); 
      return; 
     } 

     SavedState ss = (SavedState)state; 
     super.onRestoreInstanceState(ss.getSuperState()); 
     //end 

     this.stateToSave = ss.stateToSave; 
    } 

    static class SavedState extends BaseSavedState { 
     int stateToSave; 

     SavedState(Parcelable superState) { 
      super(superState); 
     } 

     private SavedState(Parcel in) { 
      super(in); 
      this.stateToSave = in.readInt(); 
     } 

     @Override 
     public void writeToParcel(Parcel out, int flags) { 
      super.writeToParcel(out, flags); 
      out.writeInt(this.stateToSave); 
     } 

     //required field that makes Parcelables from a Parcel 
     public static final Parcelable.Creator<SavedState> CREATOR = 
       new Parcelable.Creator<SavedState>() { 
        public SavedState createFromParcel(Parcel in) { 
         return new SavedState(in); 
        } 
        public SavedState[] newArray(int size) { 
         return new SavedState[size]; 
        } 
       }; 
    } 
} 
+1

was genau passiert? Code wird nicht ausgeführt? paths.size() ist immer 0? Error? bitte seien Sie klarer ... – Opiatefuchs

+0

Ich habe gerade meinen Code bearbeitet und gebe Sichtklasse zum besseren Verständnis. Vielen Dank!!! –

Antwort

2

Hier habe ich die Lösungen gefunden und es funktioniert einwandfrei.

Bitte überprüfen Sie diesen Code für Pen, Linie, Kreis, Rechteck und Rückgängig-Funktion für Sketch über das Bild:

package com.thefinal3.Sketch; 

import android.app.Activity; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Path; 
import android.graphics.PorterDuff; 
import android.graphics.PorterDuffXfermode; 
import android.os.Parcel; 
import android.os.Parcelable; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.Display; 
import android.view.MotionEvent; 
import android.view.View; 
import android.widget.Toast; 

import com.thefinal3.Bean.PathBean; 
import com.thefinal3.R; 

import java.util.ArrayList; 
import java.util.List; 

/** 
* Created by Akash patel on 11-04-2016. 
*/ 
public class DrawingView extends View { 

    protected Path mPath = new Path(); 
    public static Paint mPaint; 
    protected Bitmap mBitmap; 
    public static Canvas mCanvas; 
    public int TOUCH_TOLERANCE = 5; 
    public static int lineThickness = 5; 
    public static int ColorStroke; 
    public static int mCurrentShape; 
    public boolean isDrawing = false; 
    float mx,my,mStartX,mStartY; 

    private int stateToSave; 

    public static Paint mPaintErase = new Paint(); 
    public static Paint mPaintBitmap; 
    protected Path mPathErase = new Path(); 
    Context context; 

    private ArrayList<PathBean> paths = new ArrayList<PathBean>(); 

    public DrawingView(Context context,AttributeSet attrs) 
    { 
     super(context, attrs); 
     setFocusable(true); 
     setFocusableInTouchMode(true); 
     init(); 
     EraseLine(); 
     this.context = context; 
    } 

    protected void init() 
    { 
     mPaint = new Paint(Paint.DITHER_FLAG); 
     mPaint.setAntiAlias(true); 
     mPaint.setDither(true); 
     mPaint.setColor(getContext().getResources().getColor(R.color.colorYellow)); 
     mPaint.setStyle(Paint.Style.STROKE); 
     mPaint.setStrokeJoin(Paint.Join.ROUND); 
     mPaint.setStrokeCap(Paint.Cap.ROUND); 
     mPaint.setStrokeWidth(lineThickness); 

     ColorStroke = mPaint.getColor(); 
     lineThickness = (int)mPaint.getStrokeWidth(); 
     mCanvas = new Canvas(); 
    } 

    public Bitmap getBitmap() 
    { 
     this.setDrawingCacheEnabled(true); 
     this.buildDrawingCache(); 
     Bitmap bmp = Bitmap.createBitmap(this.getDrawingCache()); 
     this.setDrawingCacheEnabled(false); 

     return bmp; 
    } 

    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
     super.onSizeChanged(w, h, oldw, oldh); 
     mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); 
     // mCanvas.setBitmap(mBitmap); 
     mCanvas = new Canvas(mBitmap); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) 
    { 
     mx = event.getX(); 
     my = event.getY(); 

     switch (mCurrentShape) 
     { 
      case 1: 
       onTouchEventSmoothLine(event); 
       break; 

      case 2: 

      //  onTouchEventErase(event); 
       break; 

      case 3: 

       onTouchEventLine(event); 
       break; 

      case 4: 

       onTouchEventCircle(event); 
       break; 

      case 5: 

       onTouchEventRectangle(event); 
       break; 

      default: 
       break; 
     } 
     return true; 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 

     for (PathBean p : paths) 
     { 
      mPaint.setColor(p.getColor()); 
      mPaint.setStrokeWidth(p.getLineWidthStroke()); 
      switch (p.getDrawingType()) 
      { 
       case 1: 

        canvas.drawPath(p.getmPath(), mPaint); 
        Log.e("onDraw ;-->", "Path Called..."); 
        break; 

       case 2: 

        break; 

       case 3: 

        float dx1 = Math.abs(p.getMx() - p.getmStartX()); 
        float dy1 = Math.abs(p.getMy() - p.getmStartY()); 
        if (dx1 >= TOUCH_TOLERANCE || dy1 >= TOUCH_TOLERANCE) 
        { 
         canvas.drawLine(p.getmStartX(), p.getmStartY(), p.getMx(), p.getMy(), mPaint); 
         Log.e("onDraw ;-->", "Line Called..."); 
        } 
        break; 

       case 4: 

        canvas.drawCircle(p.getmStartX(), p.getmStartY(), calculateRadius(p.getmStartX(), p.getmStartY(), p.getMx(), p.getMy()), mPaint); 
        break; 

       case 5: 

        float right = p.getmStartX() > p.getMx() ? p.getmStartX() : p.getMx(); 
        float left = p.getmStartX() > p.getMx() ? p.getMx() : p.getmStartX(); 
        float bottom = p.getmStartY() > p.getMy() ? p.getmStartY() : p.getMy(); 
        float top = p.getmStartY() > p.getMy() ? p.getMy() : p.getmStartY(); 
        canvas.drawRect(left, top, right, bottom,mPaint); 
        break; 

       default: 
        break; 
      } 
     } 
     mPaint.setColor(ColorStroke); 
     mPaint.setStrokeWidth(lineThickness); 

     if (isDrawing) 
     { 
      switch (mCurrentShape) 
      { 
       case 1: 

        canvas.drawPath(mPath, mPaint); 
        break; 

       case 2: 

        break; 

       case 3: 

        onDrawLine(canvas); 
        break; 

       case 4: 

        onDrawCircle(canvas); 
        break; 

       case 5: 

        onDrawRectangle(canvas); 
        break; 

       default: 
        break; 
      } 
     } 
    } 

    //------------------------------------------------------------------ 
    // Rectangle 
    //------------------------------------------------------------------ 
    private void onTouchEventRectangle(MotionEvent event) { 

     switch (event.getAction()) 
     { 
      case MotionEvent.ACTION_DOWN: 

       isDrawing = true; 
       mStartX = mx; 
       mStartY = my; 
       invalidate(); 
       break; 

      case MotionEvent.ACTION_MOVE: 

       invalidate(); 
       break; 

      case MotionEvent.ACTION_UP: 

       isDrawing = false; 
       drawRectangle(mCanvas,mPaint); 
       PathBean bean = new PathBean(); 
       bean.setColor(ColorStroke); 
       bean.setLineWidthStroke(lineThickness); 
       bean.setmStartX(mStartX); 
       bean.setmStartY(mStartY); 
       bean.setMx(mx); 
       bean.setMy(my); 
       bean.setDrawingType(5); 
       paths.add(bean); 
       invalidate(); 
       break; 
     } 
    } 

    private void onDrawRectangle(Canvas canvas) { 
     drawRectangle(canvas, mPaint); 
    } 

    private void drawRectangle(Canvas canvas,Paint paint){ 
     float right = mStartX > mx ? mStartX : mx; 
     float left = mStartX > mx ? mx : mStartX; 
     float bottom = mStartY > my ? mStartY : my; 
     float top = mStartY > my ? my : mStartY; 
     canvas.drawRect(left, top, right, bottom, paint); 
    } 

    //------------------------------------------------------------------ 
    // Circle 
    //------------------------------------------------------------------ 
    private void onDrawCircle(Canvas canvas) { 
     canvas.drawCircle(mStartX, mStartY, calculateRadius(mStartX, mStartY, mx, my), mPaint); 
    } 

    private void onTouchEventCircle(MotionEvent event) 
    { 
     switch (event.getAction()) 
     { 
      case MotionEvent.ACTION_DOWN: 

       isDrawing = true; 
       mStartX = mx; 
       mStartY = my; 
       invalidate(); 
       break; 

      case MotionEvent.ACTION_MOVE: 

       invalidate(); 
       break; 

      case MotionEvent.ACTION_UP: 

       isDrawing = false; 
       mCanvas.drawCircle(mStartX, mStartY, 
         calculateRadius(mStartX, mStartY, mx, my), mPaint); 
       PathBean bean = new PathBean(); 
       bean.setColor(ColorStroke); 
       bean.setLineWidthStroke(lineThickness); 
       bean.setmStartX(mStartX); 
       bean.setmStartY(mStartY); 
       bean.setMx(mx); 
       bean.setMy(my); 
       bean.setDrawingType(4); 
       paths.add(bean); 
       invalidate(); 
       break; 

      default: 
       break; 
     } 
    } 

    /** 
    * @return 
    */ 
    protected float calculateRadius(float x1, float y1, float x2, float y2) { 

     return (float) Math.sqrt(
       Math.pow(x1 - x2, 2) + 
         Math.pow(y1 - y2, 2) 
     ); 
    } 

    //------------------------------------------------------------------ 
    // Line 
    //------------------------------------------------------------------ 
    private void onDrawLine(Canvas canvas) { 

     float dx = Math.abs(mx - mStartX); 
     float dy = Math.abs(my - mStartY); 
     if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) 
     { 
      canvas.drawLine(mStartX, mStartY, mx, my, mPaint); 
     } 
    } 

    private void onTouchEventLine(MotionEvent event) 
    { 
     switch (event.getAction()) 
     { 
      case MotionEvent.ACTION_DOWN: 

       isDrawing = true; 
       mStartX = mx; 
       mStartY = my; 
       invalidate(); 
       break; 

      case MotionEvent.ACTION_MOVE: 

       invalidate(); 
       break; 

      case MotionEvent.ACTION_UP: 

       isDrawing = false; 
       mCanvas.drawLine(mStartX, mStartY, mx, my, mPaint); 
       PathBean bean = new PathBean(); 
       bean.setColor(ColorStroke); 
       bean.setLineWidthStroke(lineThickness); 
       bean.setmStartX(mStartX); 
       bean.setmStartY(mStartY); 
       bean.setMx(mx); 
       bean.setMy(my); 
       bean.setDrawingType(3); 
       paths.add(bean); 
       invalidate(); 
       break; 
     } 
    } 

    //------------------------------------------------------------------ 
    // Smooth Line 
    //------------------------------------------------------------------ 
    private void onDrawSmoothLine(Canvas canvas) { 

     for (PathBean p : paths) 
     { 
      mPaint.setColor(p.getColor()); 
      canvas.drawPath(p.getmPath(), mPaint); 
     } 
     mPaint.setColor(ColorStroke); 
     canvas.drawPath(mPath, mPaint); 
    } 

    private void onTouchEventSmoothLine(MotionEvent event) 
    { 
     switch (event.getAction()) 
     { 
      case MotionEvent.ACTION_DOWN: 

       isDrawing = true; 
       mStartX = mx; 
       mStartY = my; 

       mPath.reset(); 
       mPath.moveTo(mx, my); 
       invalidate(); 
       break; 

      case MotionEvent.ACTION_MOVE: 

       float dx = Math.abs(mx - mStartX); 
       float dy = Math.abs(my - mStartY); 
       if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { 
        mPath.quadTo(mStartX, mStartY, (mx + mStartX)/2, (my + mStartY)/2); 
        mStartX = mx; 
        mStartY = my; 
       } 
       mCanvas.drawPath(mPath, mPaint); 
       invalidate(); 
       break; 

      case MotionEvent.ACTION_UP: 
       isDrawing = false; 
       mPath.lineTo(mStartX, mStartY); 
       mCanvas.drawPath(mPath, mPaint); 
     //  mPath.reset(); 
       PathBean bean = new PathBean(); 
       bean.setmPath(mPath); 
       bean.setColor(mPaint.getColor()); 
       bean.setLineWidthStroke((int)mPaint.getStrokeWidth()); 
       bean.setDrawingType(1); 
       paths.add(bean); 
       mPath = new Path(); 
       invalidate(); 
       break; 
     } 
    } 

    //------------------------------------------------------------------ 
    // Erase Line 
    //------------------------------------------------------------------ 
    public void EraseLine() 
    { 
     mPaintErase.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 
     mPaintErase.setColor(Color.TRANSPARENT); 
     mPaintErase.setAntiAlias(true); 
     mPaintErase.setDither(true); 
     mPaintErase.setStyle(Paint.Style.STROKE); 
     mPaintErase.setStrokeJoin(Paint.Join.ROUND); 
     mPaintErase.setStrokeCap(Paint.Cap.ROUND); 
     mPaintErase.setStrokeWidth(lineThickness); 

     mPaintBitmap = new Paint(Paint.DITHER_FLAG); 
    } 

    private void onTouchEventErase(MotionEvent event) 
    { 
     switch (event.getAction()) 
     { 
      case MotionEvent.ACTION_DOWN: 

       isDrawing = true; 
       mStartX = mx; 
       mStartY = my; 
       mPathErase.reset(); 
       mPathErase.moveTo(mx, my); 
       invalidate(); 
       break; 

      case MotionEvent.ACTION_MOVE: 

       float dx = Math.abs(mx - mStartX); 
       float dy = Math.abs(my - mStartY); 
       if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { 
        mPathErase.quadTo(mStartX, mStartY, (mx + mStartX)/2, (my + mStartY)/2); 
        mStartX = mx; 
        mStartY = my; 
       } 
       mCanvas.drawPath(mPathErase, mPaintErase); 
       invalidate(); 
       break; 

      case MotionEvent.ACTION_UP: 

       isDrawing = false; 
       mPathErase.lineTo(mStartX, mStartY); 
       mCanvas.drawPath(mPathErase, mPaintErase); 
      // mPathErase.reset(); 
       PathBean bean = new PathBean(); 
       bean.setmPath(mPathErase); 
       bean.setLineWidthStroke(lineThickness); 
       bean.setDrawingType(2); 
       paths.add(bean); 
       mPathErase = new Path(); 
       invalidate(); 
       break; 
     } 
    } 

    /** 
    * Undo functionality. 
    */ 
    public void onClickUndo() 
    { 
     if (paths.size()>0) 
     { 
      paths.remove(paths.size()-1); 
      invalidate(); 
     } 
     else 
     { 
      Toast.makeText(getContext().getApplicationContext(),"There is no undo action found.",Toast.LENGTH_SHORT).show(); 
     } 
    } 

    @Override 
    public Parcelable onSaveInstanceState() { 
     //begin boilerplate code that allows parent classes to save state 
     Parcelable superState = super.onSaveInstanceState(); 

     SavedState ss = new SavedState(superState); 
     //end 

     ss.stateToSave = this.stateToSave; 

     return ss; 
    } 

    @Override 
    public void onRestoreInstanceState(Parcelable state) { 
     //begin boilerplate code so parent classes can restore state 
     if(!(state instanceof SavedState)) { 
      super.onRestoreInstanceState(state); 
      return; 
     } 

     SavedState ss = (SavedState)state; 
     super.onRestoreInstanceState(ss.getSuperState()); 
     //end 

     this.stateToSave = ss.stateToSave; 
    } 

    static class SavedState extends BaseSavedState { 
     int stateToSave; 

     SavedState(Parcelable superState) { 
      super(superState); 
     } 

     private SavedState(Parcel in) { 
      super(in); 
      this.stateToSave = in.readInt(); 
     } 

     @Override 
     public void writeToParcel(Parcel out, int flags) { 
      super.writeToParcel(out, flags); 
      out.writeInt(this.stateToSave); 
     } 

     //required field that makes Parcelables from a Parcel 
     public static final Parcelable.Creator<SavedState> CREATOR = 
       new Parcelable.Creator<SavedState>() { 
        public SavedState createFromParcel(Parcel in) { 
         return new SavedState(in); 
        } 
        public SavedState[] newArray(int size) { 
         return new SavedState[size]; 
        } 
       }; 
    } 
} 
0

Sie alle Kreise ziehen, auf eine Rects Bitmap, und die Bitmap würde sich selbst nicht löschen. Wenn Sie den Pfad aus den Pfaden entfernen und die Ansicht ungültig machen, wird einfach eine Überlagerung auf die Bitmap gezeichnet.

Sie benötigen die Bitmap durch Set Farbe der Farbe Backgroundcolor und rufen mCanvas.drawRect (0, 0, mBitmap.getWidth(), mBitmap.getHeight(), mPaint) jedes Mal wenn Sie eine Undo-Aktion tun müssen, zu löschen und dann können Sie die verbleibenden Pfade neu zeichnen.

Verwandte Themen