我正在开发一个我创建绘图镜像的项目。我的主要逻辑工作正常。导致问题的唯一原因是重做和撤消功能。 我搜索了很多。实施可能的方法,但无法取得成功。以下是我的绘图课程。
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;
}
我在这里缺少什么? 任何建议/想法/例子是在我的项目中实现这种功能的最佳方式吗?
答案 0 :(得分:1)
画布绘制是一种层次结构,因为绘图按照您执行的顺序进行。
因此,所有绘图都应该在onDraw
中完成,并且只在此处完成。
您的绘制事件应该在绘制堆栈上推送。您不存储画布。您只需存储最终发生绘图时应该发生的操作(例如路径的坐标,宽度和颜色)。
&#34;撤消&#34;操作可以通过从绘图堆栈弹出并将事件推送到&#34; redo&#34;堆。 &#34;重做&#34;事件可以通过弹出&#34;重做&#34;堆叠并推回到&#34;绘图&#34;堆。
在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);
}
}
}