Android application cancel function (multitouch)

I am working on a graphical application, onTouchEvents are standard and would like to add a Undo() function to remove the last return path.

Ads:

 int thelastLineId=0; 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<Integer, Path> pathMap; // current Paths being drawn private HashMap<Integer, Path> reservedpathMap; // for saving the paths being undone private HashMap<Integer, Point> previousPointMap; // current Points 

Constructor:

 pathMap = new HashMap<Integer, Path>(); reservedpathMap = new HashMap <Integer,Path>(); // for storing path being undone previousPointMap = new HashMap<Integer, Point>(); 

Ondraw:

  @Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(bitmap, 0, 0, paintScreen); // for each path currently being drawn for (Integer key : pathMap.keySet()) canvas.drawPath(pathMap.get(key), paintLine); // draw line } 

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) { touchStarted(event.getX(actionIndex), event.getY(actionIndex), event.getPointerId(actionIndex)); } else if (action == MotionEvent.ACTION_UP) { touchEnded(event.getPointerId(actionIndex)); } else { touchMoved(event); } invalidate(); return true; } 

touchStarted:

  private void touchStarted(float x, float y, int lineID) // lineID represents how many fingers, 1 finger 1 line { Path path; // used to store the path for the given touch id Point point; // used to store the last point in path // if there is already a path for lineID if (pathMap.containsKey(lineID)) { path = pathMap.get(lineID); // get the Path path.reset(); // reset the Path because a new touch has started point = previousPointMap.get(lineID); // get Path last point } else { path = new Path(); // create a new Path pathMap.put(lineID, path); // add the Path to Map point = new Point(); // create a new Point previousPointMap.put(lineID, point); // add the Point to the Map } path.moveTo(x, y); point.x = (int) x; point.y = (int) y; } 

touchMoved:

  private void touchMoved(MotionEvent event) { // for each of the pointers in the given MotionEvent for (int i = 0; i < event.getPointerCount(); i++) { // get the pointer ID and pointer index int pointerID = event.getPointerId(i); int pointerIndex = event.findPointerIndex(pointerID); // if there is a path associated with the pointer if (pathMap.containsKey(pointerID)) { float newX = event.getX(pointerIndex); float newY = event.getY(pointerIndex); // get the Path and previous Point associated with this pointer Path path = pathMap.get(pointerID); Point point = previousPointMap.get(pointerID); float deltaX = Math.abs(newX - point.x); float deltaY = Math.abs(newY - point.y); if (deltaX >= TOUCH_TOLERANCE || deltaY >= TOUCH_TOLERANCE) { path.quadTo(point.x, point.y, ((newX + point.x)/2),((newY + point.y)/2)); point.x = (int) newX ; point.y = (int) newY ; } } } 

touchEnded:

  private void touchEnded(int lineID) { Path path = pathMap.get(lineID); // get the corresponding Path bitmapCanvas.drawPath(path, paintLine); path.reset(); } 

UNDO:

  public void undo() { Toast.makeText(getContext(), "undo button pressed" + thelastLineId, Toast.LENGTH_SHORT).show(); Path path = pathMap.get(thelastLineId); reservedpathMap.put(thelastLineId, path); // add the Path to reservedpathMap for later redo pathMap.remove(thelastLineId); invalidate(); } 

Question:

I am trying to implement the UNDO method using the code as shown above: trying to remove thelastLindId key from the HashMap pathmap (and put the HashMap reservedpathMap in the HashMap reservedpathMap for later retry) so that if invalidate() it will call OnDraw() and redraw to

 for (Integer key : pathMap.keySet()) canvas.drawPath(pathMap.get(key), paintLine); 

However, pressing the cancel button may initiate a “cancel click” toast, but the last line drawn does not disappear.

Can someone please give me the key to Undo () and Redo ()? Thank you very much in advance!

+4
source share
1 answer

As I can understand what you want to achieve, you want to be able to draw lines on the canvas and after that do UNDO functionality for your project. First of all, I think that the moment you add the path to your array should be when the user lifts a finger in your touchEnded method. Secondly, I really don’t understand what you are explaining about two / three fingers? Do you support multitouch in your canvas? Here is the implementation that I used earlier in some example to draw on canvas with canceling the implementation. Hope this helps you make things clearer:

 public void onClickUndo () { if (paths.size()>0) { undonePaths.add(paths.remove(paths.size()-1)) invalidate(); } else //toast the user } public void onClickRedo (){ if (undonePaths.size()>0) { paths.add(undonePaths.remove(undonePaths.size()-1)) invalidate(); } else //toast the user } 

and here are your touch methods:

 @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); } @Override protected void onDraw(Canvas canvas) { for (Path p : paths){ canvas.drawPath(p, mPaint); } } private float mX, mY; private static final float TOUCH_TOLERANCE = 0; private void touch_start(float x, float y) { mPath.reset(); mPath.moveTo(x, y); mX = x; mY = y; } private void touch_move(float x, float y) { float dx = Math.abs(x - mX); float dy = Math.abs(y - mY); if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2); mX = x; mY = y; } } private void touch_up() { mPath.lineTo(mX, mY); // commit the path to our offscreen mCanvas.drawPath(mPath, mPaint); // kill this so we don't double draw mPath = new Path(); paths.add(mPath); } 

As you can see here, paths are the archarist where I keep my paths. If you tell me why you need to specify your paths in hashmap, maybe I can be more useful.

+1
source

All Articles