java - Undo and Redo Functionality in android drawing app using Canvas -


i'm working on project create mirror of drawing. main logic working fine.only thing causing problem redo , undo functionality. have searched lot. implement may methods couldn't success. following drawing class.

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 drawing , 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 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 view - called after touch event @override protected void ondraw(canvas canvas) {      (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 drawing action @override public boolean ontouchevent(motionevent event) {        float touchx = event.getx();     float touchy = event.gety();     //respond down, move , 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 path 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;  } 

what missing here? suggestions/ideas/examples best way implement kind of functionality on project?

canvas drawing sort of hierarchal in drawing happens in order them.

so drawing should done in ondraw , here.

your draw events should pushed on draw stack. not store canvas. store operations supposed happen when drawing occurs (coordinates, width, , color of path example).

an "undo" operation can done popping drawing stack , pushing event "redo" stack. "redo" event can done popping "redo" stack , pushing on "drawing" stack.

in ondraw method of view, scan through drawing events , draw on canvas.

edit:

the ondraw() method iterate through drawing operations. first have interface called drawevent so:

public interface drawevent {    void draw(canvas c); } 

then in view class have collection of drawevents , iterate through them in ondraw(canvas c).

public class myview extends view {     deque<drawevent> drawevents = new linkedlist<drawevent>();      @override     public void ondraw(canvas c) {        (drawevent e : drawevents) {            e.draw(c);        }     } } 

Comments