title: How to implement undo/redo in my drawing app
body: <p>I created an app to draw and wanted to implement the functions undo / redo, I tried various methods found surfing but none of them work, can someone help me?</p>
  
  <p>Here is my code:</p>
  
  <p>Variables</p>
  
  <pre><code>'public class MainDrawingView extends View {
  public MainDrawingView(Context context, AttributeSet attrs) {
  
      super(context, attrs);
      setupDrawing();
  
  }
  
  float TOUCH_TOLERANCE = 4;
  float mX, mY;
  //drawing path
  private Path drawPath, drawX, drawY;
  //drawing and canvas paint
  private Paint drawPaint;
  private Paint canvasPaint;
  private View canvasback;
  private Paint bccanvas;
  //initial color
  private int paintColor = 0xFF000000;
  //canvas
  private Canvas drawCanvas;
  //canvas bitmap
  private Bitmap canvasBitmap, trans;
  private ArrayList&lt;Path&gt; paths = new ArrayList&lt;Path&gt;();
  private ArrayList&lt;Path&gt; undonePaths = new ArrayList&lt;Path&gt;();'
  </code></pre>
  
  <p>SetupDrawing</p>
  
  <pre><code>'private void setupDrawing() {
      drawPath = new Path();
      drawPaint = new Paint();
      bccanvas = new Paint();
      drawPaint.setColor(paintColor);
      drawPaint.setAntiAlias(true);
      drawPaint.setStrokeWidth(20);
      drawPaint.setStyle(Paint.Style.FILL_AND_STROKE);
      drawPaint.setStrokeJoin(Paint.Join.ROUND);
      drawPaint.setStrokeCap(Paint.Cap.ROUND);
      canvasPaint = new Paint(Paint.DITHER_FLAG);
  
  }'
  </code></pre>
  
  <p>onSizeChanged</p>
  
  <pre><code>'@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);
      drawCanvas = new Canvas(canvasBitmap);
  
  }'
  </code></pre>
  
  <p>Touch Event</p>
  
  <pre><code>'private void touch_start(float x, float y) {
      undonePaths.clear();
      drawPath.reset();
      drawPath.moveTo(x, y);
  
      mX = x;
      mY = y;
  }
  
  private void touch_move(float x, float y) {
      float dx, dy;
      dx = Math.abs(x - mX);
      dy = Math.abs(y - mY);
      if ((dx &gt;= TOUCH_TOLERANCE) || (dy &gt;= TOUCH_TOLERANCE)) {
          drawPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
          drawPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
          drawPath.lineTo(mX, mY);
          // commit the path to our offscreen
          drawCanvas.drawPath(drawPath, drawPaint);
          drawPath.reset();
          drawPath.moveTo(mX, mY);
  
  
          mX = x;
          mY = y;
      }
  }
  
  private void touch_up() {
      drawPath.reset();
  
  }'
  </code></pre>
  
  <p>onTouchEvent</p>
  
  <pre><code>'public boolean onTouchEvent(MotionEvent event) {
      float x = event.getX();
      float y = event.getY();
      switch (event.getAction()) {
          case MotionEvent.ACTION_DOWN:
  
              touch_start(x, y);
              drawPath.moveTo(x, y);
  
              break;
          case MotionEvent.ACTION_MOVE:
  
              touch_move(x, y);
              drawPath.lineTo(x, y);
              invalidate();
              break;
          case MotionEvent.ACTION_UP:
              drawPath.reset();
              touch_up();
  
              invalidate();
              break;
      }
      return true;
  }'
  </code></pre>
  
  <p>onDraw</p>
  
  <pre><code>'@SuppressLint("NewApi")
  @Override
  protected void onDraw(Canvas canvas) {
  
          canvas.drawPath(p, drawPaint);
          canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
      }'
  </code></pre>
  
  <p>onClickUndo</p>
  
  <pre><code>'public void onClickUndo () {
          if (paths.size()&gt;0){
  
          undonePaths.add(paths.remove(paths.size()-1));
          invalidate();
          undonePaths.clear();
      }
      else
      {
  
      }
      //toast the user
  }'
  </code></pre>
  
  <p>onClickRedo</p>
  
  <pre><code>'public void onClickRedo (){
      if (undonePaths.size()&gt;0)
      {
          paths.add(undonePaths.remove(undonePaths.size()-1));
          invalidate();
      }
      else
      {
  
      }
      //toast the user
  }'
  </code></pre>