title: Android: Painting app with eraser not working
body: <p>I am working on a painting app, with undo/redo function and would like to add eraser function.</p>
  
  <h2>Code for MainActivity</h2>
  
  <pre><code>case R.id.undoBtn:          
       doodleView.onClickUndo();          
       break;
  
  case R.id.redoBtn:          
       doodleView.onClickRedo();          
       break;
  
  case R.id.eraserBtn:            
       Constants.mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); break; 
  </code></pre>
  
  <h2>         DrawView</h2>
  
  <pre><code>// Drawing Part    
      private Bitmap mBitmap;   
      private Paint  mBitmapPaint;
      private Canvas mCanvas; 
      private Path   mPath; 
      private int selectedColor = Color.BLACK;
      private int selectedWidth = 5;
  
      private ArrayList&lt;Path&gt; paths = new ArrayList&lt;Path&gt;();
      private ArrayList&lt;Path&gt; undonePaths = new ArrayList&lt;Path&gt;();
      private Map&lt;Path, Integer&gt; colorsMap = new HashMap&lt;Path, Integer&gt;();
      private Map&lt;Path, Integer&gt; widthMap = new HashMap&lt;Path, Integer&gt;();
  
      private float mX, mY;
      private static final float TOUCH_TOLERANCE = 4; 
      Context context_new;
  
     public DoodleView(Context c, AttributeSet attrs) 
     {
         super(c, attrs);
         context_new = c;    
         setFocusable(true);
         setFocusableInTouchMode(true);
         setLayerType(View.LAYER_TYPE_SOFTWARE, null); // for solely removing the black eraser
  
         mPath = new Path(); 
         mCanvas = new Canvas();  
         mBitmapPaint = new Paint(Paint.DITHER_FLAG);   
  
         Constants.mPaint = new Paint();
         Constants.mPaint.setAntiAlias(true); // smooth edges of drawn line
         Constants.mPaint.setDither(true);
         Constants.mPaint.setColor(Color.BLACK); // default color is black
         Constants.mPaint.setStyle(Paint.Style.STROKE); // solid line
         Constants.mPaint.setStrokeJoin(Paint.Join.ROUND);
         Constants.mPaint.setStrokeWidth(20); // set the default line width
         Constants.mPaint.setStrokeCap(Paint.Cap.ROUND); // rounded line ends 
         Constants.mPaint.setXfermode(null);
         Constants.mPaint.setAlpha(0xFF);
     } 
  
     @Override
     public void onSizeChanged(int w, int h, int oldW, int oldH)
     {
         super.onSizeChanged(w, h, oldW, oldH);
         mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
  
        Constants.DRAW_W = w;
        Constants.DRAW_H = h;
        Log.d("TAG", "onSizeChanged!!!" + Constants.DRAW_W + Constants.DRAW_H + Constants.SCREEN_W + Constants.SCREEN_H);   
        // bitmap.eraseColor(Color.WHITE); // erase the BitMap with white    
     }   
  
     @Override
     protected void onDraw(Canvas canvas) 
     {
         canvas.drawBitmap(mBitmap, 0, 0, null); // draw the background screen
  
         for (Path p : paths)
         {
             Constants.mPaint.setColor(colorsMap.get(p));
             Constants.mPaint.setStrokeWidth(widthMap.get(p));
             canvas.drawPath(p, Constants.mPaint);           
         }       
         Constants.mPaint.setColor(selectedColor);
         Constants.mPaint.setStrokeWidth(selectedWidth);
         canvas.drawPath(mPath, Constants.mPaint);                   
     } 
  
     @Override
     public boolean onTouchEvent(MotionEvent event) 
     {          
            float x = event.getX();
            float y = event.getY();
  
            switch (event.getAction())
            {
                case MotionEvent.ACTION_DOWN:
                     touch_start(x, y);
                     invalidate();
                     break;
                case MotionEvent.ACTION_MOVE:
                     touch_move(x, y);
                     invalidate();
                     break;
                case MotionEvent.ACTION_UP:
                     touch_up();
                     invalidate();
                     break;
            }
            return true;
      }
  
     private void touch_start(float x, float y) 
     {
         undonePaths.clear();
         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 &gt;= TOUCH_TOLERANCE || dy &gt;= TOUCH_TOLERANCE) 
         {
             mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
             mX = x;
             mY = y;
  
             startdrawing = true;
         }
     }
  
     private void touch_up() 
     {
         mPath.lineTo(mX, mY);      
         mCanvas.drawPath(mPath, Constants.mPaint); 
         paths.add(mPath);
         colorsMap.put(mPath,selectedColor);
         widthMap.put(mPath,selectedWidth);
         mPath = new Path(); 
     }
  
     public void onClickUndo() 
     { 
         if (paths.size()&gt;0) 
          { 
             undonePaths.add(paths.remove(paths.size()-1));
             invalidate();
          }      
         else Toast.makeText(getContext(), R.string.toast_nothing_to_undo, Toast.LENGTH_SHORT).show();  
      }
  
     public void onClickRedo()
     {
         if (undonePaths.size()&gt;0) 
         { 
             paths.add(undonePaths.remove(undonePaths.size()-1)); 
             invalidate();
         } 
         else 
             Toast.makeText(getContext(), R.string.toast_nothing_to_redo, Toast.LENGTH_SHORT).show(); 
      }  
  
     public void setDrawingColor(int color)
     {       
         selectedColor = color;
         Constants.mPaint.setColor(color);
     } 
  
     public int getDrawingColor()
     {
        return Constants.mPaint.getColor();
     } 
  </code></pre>
  
  <h2>Question:</h2>
  
  <p>Normal painting and undo / redo can be performed perfectly. However, the eraser does not work. </p>
  
  <ol>
  <li><p>After pressing  (<code>touch_start</code>) the eraser button and touch the screen, all the previous drawn line immediately turn black. </p></li>
  <li><p>When using the eraser upon <code>touch_move</code> , the eraser itself is drawing black lines, even though it was on <code>CLEAR</code> mode.</p></li>
  <li><p>Upon <code>touch_up</code>, All other drawn lines maintained at black color. The "erased" area was also in black color. However, when drawing a new path subsequently, the original line turned to their original color, the area "erased" by the eraser turn its color to the last color chosen and the paths retained in the View.</p></li>
  </ol>
  
  <p>How could the code on eraser be written in a proper way? (keeping undo / redo)</p>
  
  <p>Thanks a lot in advance!</p>