我正在制作一个绘图应用程序,并希望实现一个撤消function来删除前一个绘制的路径。
编码:
private HashMap pathMap; // current Paths being drawn private HashMap previousPointMap; // current Points private Bitmap bitmap; // drawing area for display or saving private Canvas bitmapCanvas; // used to draw on bitmap private Paint paintScreen; // use to draw bitmap onto screen private Paint paintLine; // used to draw lines onto bitmap public DrawView(Context context, AttributeSet attrs) { super(context, attrs); // pass context to View's constructor this.context_new=context; paintScreen = new Paint(); // used to display bitmap onto screen // set the initial display settings for the painted line paintLine = new Paint(); paintLine.setAntiAlias(true); // smooth edges of drawn line paintLine.setColor(Color.BLACK); // default color is black paintLine.setStyle(Paint.Style.STROKE); // solid line paintLine.setStrokeWidth(5); // set the default line width paintLine.setStrokeCap(Paint.Cap.ROUND); // rounded line ends pathMap = new HashMap(); previousPointMap = new HashMap(); } // end DrawView constructor @Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(bitmap, 0, 0, paintScreen); for (Integer key : pathMap.keySet()) canvas.drawPath(pathMap.get(key), paintLine); } // called when the user finishes a touch private void touchEnded(int lineID) { Path path = pathMap.get(lineID); // get the corresponding Path bitmapCanvas.drawPath(path, paintLine); // draw to bitmapCanvas path.reset(); // reset the Path rememberLineId = lineID; } // end method touch_ended //undo private void undo() { Path path = pathMap.get(rememberLineId); // get the corresponding Path pathMap.remove(rememberLineId); bitmapCanvas.clearPath(path, paintLine); path.reset(); // reset the Path }
题:
但是,似乎没有bitmapCanvas.clearPath这种方法? 如果那么它怎么可能被修改?
代码修订:
声明:
private Bitmap bitmap; // drawing area for display or saving private Canvas bitmapCanvas; // used to draw on bitmap private Paint paintScreen; // use to draw bitmap onto screen private Paint paintLine; // used to draw lines onto bitmap private HashMap pathMap; // current Paths being drawn private HashMap previousPointMap; // current Points private Bitmap bitmapBackup;
OnSizeChanged
@Override public void onSizeChanged(int w, int h, int oldW, int oldH) { super.onSizeChanged(w, h, oldW, oldH); DoodlzViewWidth = w; DoodlzViewHeight = h; bitmapBackup = Bitmap.createBitmap(getWidth(), DoodlzViewHeight, Bitmap.Config.ARGB_8888); bitmap = Bitmap.createBitmap(getWidth(), DoodlzViewHeight, Bitmap.Config.ARGB_8888); bitmapCanvas = new Canvas(bitmap); bitmap .eraseColor(Color.WHITE); // erase the BitMap with white bitmapBackup.eraseColor(Color.WHITE); }
FirsttoBackup方法,将在下面的TouchedStart执行时调用
public void firsttobackup() { bitmapBackup=bitmap; Toast message = Toast.makeText(getContext(), "backuped 123", Toast.LENGTH_SHORT); message.show(); //THIS TOAST CAN BE SUCESSFULLY PRESENTED when touching screen starting to draw }
的OnDraw
@Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(bitmap, 0, 0, paintScreen); for (Integer key : pathMap.keySet()) canvas.drawPath(pathMap.get(key), paintLine);
}
的onTouchEvent
@Override public boolean onTouchEvent(MotionEvent event) { int action = event.getActionMasked(); // event type int actionIndex = event.getActionIndex(); // pointer (ie, finger) if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_DOWN) { firsttobackup(); //TOAST CAN SHOW "BACKUP 123" touchStarted(event.getX(actionIndex), event.getY(actionIndex), event.getPointerId(actionIndex)); }
撤消:用户按下撤消按钮将调用此按钮
public void undo() { bitmap = bitmapBackup.copy(Bitmap.Config.ARGB_8888, true); bitmapCanvas = new Canvas(bitmap); }
问题修订:
现在使用firsttobackup()方法,以便bitmapBackup在执行OnTouchEvent touchStarted时设置= bitmap。 我已经为它做了一个祝酒词,当用户按下屏幕开始画画时,它会被提供“备份123”。
当用户单击撤消按钮时,它将调用undo方法,但现在按下撤消按钮,无法看到任何操作……为什么?
谢谢!!
我认为最简单的方法是使用2个位图(1个额外的备份位图用于恢复以前的状态)。
在开始新绘图之前,需要保存位图的先前状态。
以下是我将如何修改您的代码:
private HashMappathMap; // current Paths being drawn private HashMappreviousPointMap; // current Points private Bitmap bitmap; // drawing area for display or saving private Bitmap bitmapBackup; private Canvas bitmapCanvas; // used to draw on bitmap private Canvas bitmapBackupCanvas; // remember last bitmap before new drawings... private void touchStarted() { bitmapBackupCanvas.drawBitmap(bitmap, 0, 0, null); } // called when the user finishes a touch private void touchEnded(int lineID) { Path path = pathMap.get(lineID); // get the corresponding Path bitmapCanvas.drawPath(path, paintLine); // draw to bitmapCanvas path.reset(); // reset the Path rememberLineId = lineID; } // end method touch_ended //undo private void undo() { Path path = pathMap.get(rememberLineId); // get the corresponding Path pathMap.remove(rememberLineId); bitmapCanvas.drawBitmap(bitmapBackup, 0, 0, null); // restore from backup path.reset(); // reset the Path }
乍一看,我看到以下问题:
通过在创建Path将空Path添加到paths ,一旦撤消就会出现问题:您首先popup该空Path ,使第一个撤消似乎不起作用。 然后,如果您绘制到该Path ,则不会将其添加到paths 。 解决方案是在创建新路径之前将完成的Path添加到touch_up()路径。
也就是说,删除
paths.add(mPath);
从构造函数,并在touch_up() ,更改
mPath = new Path(); paths.add(mPath);
至
paths.add(mPath); mPath = new Path();
你还想要添加
canvas.drawPath(mPath, mPaint);
在onDraw()中for循环后,以绘制正在进行的Path 。
当用户再次开始绘制时,您不会清空undonePaths 。
如果您使用PorterDuffXfermode ,请将视图保存到您的bitmapBackup ,而不是之前的位图
public void undo (){ bitmap.eraseColor(getDrawingCacheBackgroundColor()); mCanvas.drawBitmap(bitmapBackup, 0, 0, null); invalidate(); mPath.reset(); undofresh=true; } private void touch_start(float x, float y) { View v1 = this; v1.setDrawingCacheEnabled(true); this.bitmapBackup = Bitmap.createBitmap(v1.getDrawingCache()); v1.setDrawingCacheEnabled(false); }
use path.reset()in the MotionEvent.ACTION_DOWN event of OnTouchEvent() method. @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mPath.reset(); invalidate(); break; } return true; }