我正在做一个项目,在其中创建绘图的镜像。我的主要逻辑工作正常。导致问题的唯一原因是重做和撤消功能。
我已经搜索了很多。实现可能的方法,但无法成功。以下是我的绘画课。

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;

}


我在这里想念什么?
有什么建议/想法/示例是在我的项目上实现此类功能的最佳方法吗?

最佳答案

画布绘制是一种层次结构,其中绘制按您执行的顺序进行。

因此,所有绘制都应在onDraw中完成,并且仅在此处进行。

您的抽奖事件应推送到抽奖堆栈中。您不存储画布。您只需存储在图形最终出现时应该发生的操作(例如,坐标,宽度和路径的颜色)。

可以通过从图形堆栈弹出并将事件推送到“重做”堆栈来完成“撤消”操作。可以通过从“重做”堆栈弹出并推回“绘图”堆栈来完成“重做”事件。

在View的onDraw方法中,只需扫描绘图事件并在画布上绘制即可。

编辑:

onDraw()方法将仅遍历您的绘制操作。因此,首先您可以拥有一个名为interfaceDrawEvent,如下所示:

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


然后,在您的View类中,保存您的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);
       }
    }
}

关于java - 使用Canvas在Android绘图应用程序中的撤消和重做功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38700518/

10-09 00:40