我正在做一个项目,在其中创建绘图的镜像。我的主要逻辑工作正常。导致问题的唯一原因是重做和撤消功能。
我已经搜索了很多。实现可能的方法,但无法成功。以下是我的绘画课。
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()
方法将仅遍历您的绘制操作。因此,首先您可以拥有一个名为interface
的DrawEvent
,如下所示:
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/