2015-02-23 31 views
0

我想刪除我的畫布上繪製的最後一條路徑。我已嘗試到目前爲止添加我的路徑在ArrayList中,但我沒有找到任何方法從畫布中刪除路徑easilly。如何從Canvas android中撤消路徑?

public class PaintView extends View { 

    private Bitmap mBitmap; 
    private Canvas mCanvas; 
    private Path mPath; 
    private Paint mPaint; 
    private static final int TOUCH_TOLERANCE_DP = 20; 
    private static final int BACKGROUND = Color.TRANSPARENT; 
    private List<Point> mPoints = new ArrayList<Point>(); 
    private int mLastPointIndex = 0; 
    private int mTouchTolerance; 
    private boolean isPathStarted = false; 
    private boolean canCreatePoints = true; 
    private Polygon poly; 
    private Builder build; 
    private ArrayList<Polygon> polyList; 
    private ArrayList<Path> undoPath, redoPath; 

    public PaintView(Context context) { 
     super(context); 
     mCanvas = new Canvas(); 
     mPath = new Path(); 
     mPaint = new Paint(); 
     mPaint.setAntiAlias(true); 
     mPaint.setDither(true); 
     mPaint.setColor(Color.BLACK); 
     mPaint.setStyle(Paint.Style.STROKE); 
     mPaint.setStrokeJoin(Paint.Join.ROUND); 
     mPaint.setStrokeCap(Paint.Cap.ROUND); 
     mPaint.setStrokeWidth(12); 
     mTouchTolerance = dp2px(TOUCH_TOLERANCE_DP); 

     polyList = new ArrayList<Polygon>(); 
     undoPath = new ArrayList<Path>(); 
     redoPath = new ArrayList<Path>(); 
    } 

    @Override 
    protected void onSizeChanged(int width, int height, int oldWidth, 
      int oldHeight) { 
     super.onSizeChanged(width, height, oldWidth, oldHeight); 
     clear(); 

    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     canvas.drawColor(BACKGROUND); 
     canvas.drawBitmap(mBitmap, 0, 0, null); 
     canvas.drawPath(mPath, mPaint); 

     for(Path p : undoPath) { 
      canvas.drawPath(p, mPaint); 
     } 

     for (Point point : mPoints) { 
      canvas.drawPoint(point.x, point.y, mPaint); 
     } 

    } 

下面是onTouch方法,我創建一個使用路徑線時可變canCreatePoints它true.If canCreatePoints這是假的我在一個ArrayList<Polygon>檢查我的接觸點是多邊形內。

@Override 
public boolean onTouchEvent(MotionEvent event) { 
float x = event.getX(); 
float y = event.getY(); 

switch (event.getAction()) { 
case MotionEvent.ACTION_DOWN: 
    if(canCreatePoints == true) 
    { 
     create_point(x,y); 

     if(mPoints.size() > 1) 
     { 
      // start point 
      Point p = mPoints.get(mLastPointIndex); 
      mPath.moveTo(p.x, p.y); 
      // end point 
      p = mPoints.get(mLastPointIndex + 1); 
      mPath.lineTo(p.x, p.y); 
      mCanvas.drawPath(mPath, mPaint); 

      undoPath.add(mPath); 

      mPath.reset(); 
      // increment point index 
      ++mLastPointIndex; 
     } 
    } 

    if(canCreatePoints == false) 
    { 
     Points pp = new Points(Math.round(x), Math.round(y)); 
     boolean contains; 

     for(Polygon tempPoly:polyList){ 
      contains = tempPoly.contains(pp); 
      if(contains == true) 
      { 
       Log.i("TEST","Poligonul contine punctul"); 
       Toast.makeText(getContext(),"Test poly "+polyList.indexOf(tempPoly), 
         Toast.LENGTH_SHORT).show(); 
      } 
     } 

     } 
     invalidate(); 
     break; 
    } 
    return true; 
} 

private void create_point(float x, float y){ 
    Point p = new Point(Math.round(x),Math.round(y)); 
    mPoints.add(p); 
} 

貝婁我通過按鈕的動作芬蘭我的多邊形形式。我創建了一個從最後一點到第一點的路徑並在畫布上繪製。

public void finnishDraw(){ 
    if(mPoints.size() > 1) 
    { 
     // start point 
     Point p = mPoints.get(0); 
     mPath.moveTo(p.x, p.y); 
     // end point 
     p = mPoints.get(mPoints.size() - 1); 
     mPath.lineTo(p.x, p.y); 
     mCanvas.drawPath(mPath, mPaint); 
     mPath.reset(); 
     invalidate(); 

     int x[] = new int[mPoints.size()]; 
     int y[] = new int[mPoints.size()]; 

     build = new Builder(); 

     for(int i=0 ; i<mPoints.size() ; i++) 
     { 
      p = mPoints.get(i); 
      x[i] = p.x; 
      y[i] = p.y; 

      build.addVertex(new Points(x[i],y[i])); 

      Log.i("TEST","Adaug la builder punctele "+x[i]+" si "+y[i]); 
     } 

     poly = build.build(); 

     polyList.add(poly); 
     mPoints.clear(); 
     mLastPointIndex = 0; 

    } 
} 

到目前爲止,我只找到一個備用位圖解決畫線之前,但我不明白它是如何真正起作用。

回答

0

您無法撤銷畫布上的drawPath。從documentation

通過畫布,你的繪畫實際上是在底層 位圖,它被放置在窗口中執行。

正如你所說,你需要一個備份位圖在繪製之前保存當前位圖的狀態,例如使用Memento pattern

看看Fast undo/redo for bitmap editor when memory is limited?Fast undo facility for bitmap editor application(最後一個靶向iPhone,但基本思想是相同的)

另一種方法更少的內存,可以節省您要借鑑對象的狀態消耗你的畫布並根據需要繪製它們(當您需要顯示部分或全部結果時)。