2016-08-01 101 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。 –

相关问题