2016-08-01 69 views
2

我正在創建一個項目,在其中創建繪圖的鏡像。我的主要邏輯工作正常。只有造成問題的原因是重做和撤消功能。 我搜索了很多。實施可能的方法,但無法取得成功。以下是我的繪畫課。使用畫布在Android繪圖應用程序中撤消和重做功能

DrawingView.java

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

public DrawingView(Context context, AttributeSet attrs){ 
    super(context, attrs); 
    this.context=context; 
    setupDrawing(); 


} 

//setup drawing 
private void setupDrawing(){ 

    //prepare for drawing and setup paint stroke properties 
    brushSize = getResources().getInteger(R.integer.small_size); 
    lastBrushSize = brushSize; 
    drawPath = new Path(); 
    drawPath1 = new Path(); 
    drawPaint = new Paint(); 
    drawPaint.setColor(paintColor); 
    drawPaint.setAntiAlias(true); 
    drawPaint.setStrokeWidth(brushSize); 
    drawPaint.setStyle(Paint.Style.STROKE); 
    drawPaint.setStrokeJoin(Paint.Join.ROUND); 
    drawPaint.setStrokeCap(Paint.Cap.ROUND); 
    canvasPaint = new Paint(Paint.DITHER_FLAG); 
} 

//size assigned to view 
@Override 
protected void onSizeChanged(int w, int h, int oldw, int oldh) { 


    super.onSizeChanged(w, h, oldw, oldh); 
    canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); 
    width=w; 
    height=h; 
    Log.d("width,height", w + " , " + h); 
    drawCanvas = new Canvas(canvasBitmap); 




} 

//draw the view - will be called after touch event 
@Override 
protected void onDraw(Canvas canvas) { 

    for (Path p : paths){canvas.drawPath(p, drawPaint);} 
    canvas.drawPath(drawPath, drawPaint); 
    Log.i("OnDRAWING", "REACH ON DRAW"); 
    /*canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint); 
    canvas.drawPath(drawPath, drawPaint); 
    canvas.drawPath(drawPath1, drawPaint);*/ 






} 

//register user touches as drawing action 
@Override 
public boolean onTouchEvent(MotionEvent event) { 



    float touchX = event.getX(); 
    float touchY = event.getY(); 
    //respond to down, move and up events 
    switch (event.getAction()) { 
    case MotionEvent.ACTION_DOWN: 
     drawPath.reset(); 
     undonePaths.clear(); 
     drawPath.moveTo(touchX, touchY); 
     undonePaths.clear(); 



     break; 
    case MotionEvent.ACTION_MOVE: 
     drawPath.lineTo(touchX, touchY); 


     break; 
    case MotionEvent.ACTION_UP: 
     drawPath.lineTo(touchX, touchY); 
     drawCanvas.drawPath(drawPath, drawPaint);// commit the path to our offscreen 
     paths.add(drawPath); 
     drawCanvas.drawPath(drawPath, drawPaint); 
     drawPath.reset(); 

     drawCanvas.drawPath(drawPath1, drawPaint); 
     drawPath1.reset(); 

     break; 
    default: 
     return false; 
    } 
    //redraw 
    invalidate(); 
    return true; 

} 

什麼,我在這裏失蹤? 任何建議/想法/例子,這是在我的項目上實現這種功能的最佳方式?

回答

1

畫布畫是一種分層次的圖畫,按照你做的順序進行。

所以所有的繪圖都應該在onDraw中完成,只有在這裏。

您的繪畫事件應該放在繪製堆棧上。你不存儲畫布。您只需存儲繪圖最終發生時應該發生的操作(例如,路徑的座標,寬度和顏色)。

「撤消」操作可以通過彈出繪圖堆棧並將事件推送到「重做」堆棧來完成。 「重做」事件可以通過從「重做」堆棧中彈出並重新推回到「繪圖」堆棧來完成。

在您的視圖的onDraw方法中,只需掃描繪圖事件並在畫布上繪製即可。

編輯:

onDraw()方法只會通過你的繪製操作迭代。所以,首先你可以有一個interface稱爲DrawEvent像這樣:

public interface DrawEvent { 
    void draw(Canvas c); 
} 

然後在您的視圖類有你的DrawEvents收集,並通過他們在onDraw(Canvas c)迭代。

public class MyView extends View { 
    Deque<DrawEvent> drawEvents = new LinkedList<DrawEvent>(); 

    @Override 
    public void onDraw(Canvas c) { 
     for (DrawEvent e : drawEvents) { 
      e.draw(c); 
     } 
    } 
} 
+0

感謝您的快速響應。我瞭解流程。你能告訴我我應該寫什麼嗎?它對我來說有點困惑。我會感謝任何幫助。 –

+0

我編輯它以顯示onDraw方法如何工作。我試圖解決的問題是,您無法在視圖的'onDraw'或'draw'方法之外保存或使用Canvas。您必須存儲有關如何繪製和保持它們的順序的事件和說明。 – DeeV

+0

我正在添加路徑列表之前。現在當我實現一個接口時,我很困惑在哪裏添加和添加drawEvents。 –

相關問題