title: How to draw rectangle on touch event
body: <p>How to draw rectangle on touch event in android. I have a canvas when I am touching on the canvas, its drawing a rectangle but when I touch on new location it remove the old rectangle and draw a new rectangle on new location. But, I want to keep all rectangle visible wherever I have touched.</p>
  
  <pre><code>public class TouchImageView extends ImageView {
  
      Matrix matrix = new Matrix();
  
      // We can be in one of these 3 states
  
      static final int NONE = 0;
  
      static final int DRAG = 1;
  
      static final int ZOOM = 2;
  
      boolean isCheckLoadImage = false;
  
      public static boolean isDraw = false;
  
      int mode = NONE;
  
      private float mPosX;
  
      private float mPosY;
  
      public static int numCell1 = 0;
  
      public static boolean CorrectTouch;
  
      float boxHeight, boxWidth;
  
      // Remember some things for zooming
  
      PointF last = new PointF();
  
      PointF start = new PointF();
  
      float minScale = 1f;
  
      float maxScale = 6f;
  
      int lastTouchEvent = -1;
  
      int selectedCell;
  
      float[] m;
  
      float scaleWidth, scaleHeight;
  
      float redundantXSpace, redundantYSpace;
  
      float width, height;
  
      static final int CLICK = 3;
  
      float saveScale = 1f;
  
      float right, bottom, origWidth, origHeight, bmWidth, bmHeight;
  
      ScaleGestureDetector mScaleDetector;
  
      Context context;
  
      boolean flag = false;
  
  
      public TouchImageView(Context context) {
  
          super(context);
  
          sharedConstructing(context);
  
      }
  
      public TouchImageView(Context context, AttributeSet attrs) {
  
          super(context, attrs);
  
          sharedConstructing(context);
  
      }
  
      @Override
      protected void onDraw(Canvas canvas) {
  
          super.onDraw(canvas);
  
          Paint paint = new Paint();
  
          paint.setColor(Color.RED);
  
          paint.setStyle(Paint.Style.STROKE);
  
          paint.setStrokeWidth(4);
  
          RectF r = new RectF();
  
          matrix.mapRect(r);
  
          boxWidth = scaleWidth / 5;
  
          boxHeight = scaleHeight / 5;
  
          float widthOfCell = boxWidth;
  
          float heightOfCell = boxHeight;
  
          float[] touchPoint = new float[] { mPosX, mPosY };
  
          float[] newTouch = new float[] { 0, 0 };
  
          matrix.mapPoints(newTouch, touchPoint);
  
          RectF canvasRect = new RectF();
  
          canvas.getMatrix().mapRect(canvasRect);
  
          Log.i("canvasRect", "canvasRect.left : " + canvasRect.left
                  + " canvasRect.top : " + canvasRect.top);
  
          Log.i("r", "r.left : " + r.left + " r.top : " + r.top);
  
          Log.i("Pos", "mPosX : " + mPosX + " mPosY : " + mPosY);
  
          float newX = mPosX - (r.left);
  
          float newY = mPosY - (r.top);
  
          Log.i("new XY", "New X" + newX + " NewY " + newY);
  
          int myX = (int) (newX / boxWidth); /* Columns */
  
          int myY = (int) (newY / boxHeight);/* Rows */
  
          Log.i("my XY", "myX " + myX + " myY " + myY);
  
          //
  
          Log.e("GuessImageView", "before grid draw");
  
          try {
  
              if (true) {
  
                  if (lastTouchEvent == MotionEvent.ACTION_UP) {
  
                      numCell1 = 0;
  
                      boolean doBreak = false;
  
                      for (float row = 0; !doBreak
                              &amp;&amp; row &lt;5; row++) {
  
                          float y = (row * heightOfCell) + r.top;
  
                          for (float col = 0; col &lt; 5; col++) {
  
                              float x = (col * widthOfCell) + r.left;
  
                              if ((int) col == myX &amp;&amp; (int) row == myY) {
  
                                  canvas.drawRect(x, y, x + widthOfCell, y
                                          + heightOfCell, paint);
  
                                  Log.d("Touch X : " + x, "Touch Y : " + y);
  
                                  selectedCell = numCell1;
  
                                  numCell1++;
  
                                  flag = true;
  
                                  doBreak = true;
  
                                  break;
  
                              }
  
                              numCell1++;
  
                          }
  
                      }
  
                      if (flag) {
  
                          isCheckLoadImage = true;
  
  //                      guessImage.checkForWin(selectedCell);
  
                      }
  
                      Log.i("Touch ", "Number Of Cell&gt;" + numCell1);
  
                      lastTouchEvent = -1;
  
                  }
  
              }
  
          } catch (ArithmeticException e) {
  
              e.printStackTrace();
  
          }
  
          Log.e("GuessImageView", "after grid draw");
  
      }
  
      private void sharedConstructing(Context context) {
  
          super.setClickable(true);
  
          this.context = context;
  
          mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
  
          matrix.setTranslate(1f, 1f);
  
          m = new float[9];
  
          setImageMatrix(matrix);
  
          setScaleType(ScaleType.MATRIX);
  
          setOnTouchListener(new OnTouchListener() {
  
              @Override
              public boolean onTouch(View v, MotionEvent event) {
  
                  mScaleDetector.onTouchEvent(event);
  
                  matrix.getValues(m);
  
                  float x = m[Matrix.MTRANS_X];
  
                  float y = m[Matrix.MTRANS_Y];
  
                  PointF curr = new PointF(event.getX(), event.getY());
  
                  switch (event.getAction()) {
  
                  case MotionEvent.ACTION_DOWN:
  
                      last.set(event.getX(), event.getY());
  
                      start.set(last);
  
                      mode = DRAG;
  
                      // isDraw=false;
  
                      break;
  
                  case MotionEvent.ACTION_MOVE:
  
                      // Log.i("onTouch", "origWidth : " + origWidth +
  
                      // " origHeight : " + origHeight);
  
                      if (mode == DRAG) {
  
                          // isDraw=false;
  
                          float deltaX = curr.x - last.x;
  
                          float deltaY = curr.y - last.y;
  
                          scaleWidth = Math.round(origWidth * saveScale);
  
                          scaleHeight = Math.round(origHeight * saveScale);
  
                          if (scaleWidth &lt; width) {
  
                              deltaX = 0;
  
                              if (y + deltaY &gt; 0)
  
                                  deltaY = -y;
  
                              else if (y + deltaY &lt; -bottom)
  
                                  deltaY = -(y + bottom);
  
                          } else if (scaleHeight &lt; height) {
  
                              deltaY = 0;
  
                              if (x + deltaX &gt; 0)
  
                                  deltaX = -x;
  
                              else if (x + deltaX &lt; -right)
  
                                  deltaX = -(x + right);
  
                          } else {
  
                              if (x + deltaX &gt; 0)
  
                                  deltaX = -x;
  
                              else if (x + deltaX &lt; -right)
  
                                  deltaX = -(x + right);
  
                              if (y + deltaY &gt; 0)
  
                                  deltaY = -y;
  
                              else if (y + deltaY &lt; -bottom)
  
                                  deltaY = -(y + bottom);
  
                          }
  
                          matrix.postTranslate(deltaX, deltaY);
  
                          last.set(curr.x, curr.y);
  
                      }
  
                      break;
  
                  case MotionEvent.ACTION_UP: {
  
                      mode = NONE;
  
                      int xDiff = (int) Math.abs(curr.x - start.x);
  
                      int yDiff = (int) Math.abs(curr.y - start.y);
  
                      if (xDiff &lt; CLICK &amp;&amp; yDiff &lt; CLICK) {
  
                          // isDraw=false;
  
                          Log.v("ACTION_UP", "ACTION_UP");
  
                          mPosX = curr.x;
  
                          mPosY = curr.y;
  
                          performClick();
  
  //                      if (guessImage.guess_mode) {
  
                              lastTouchEvent = event.getAction();
                          /*}
  
                          else {
  
                              lastTouchEvent = -1;
  
                          }
  */
                          // invalidate();
  
                      }
  
                      break;
  
                  }
  
                  case MotionEvent.ACTION_POINTER_UP:
  
                      mode = NONE;
  
                      break;
  
                  }
  
                  setImageMatrix(matrix);
  
                  scaleWidth = Math.round(origWidth * saveScale);
  
                  scaleHeight = Math.round(origHeight * saveScale);
  
                  invalidate();
  
                  return true; // indicate event was handled
  
              }
  
          });
  
      }
  
      @Override
      public void setImageBitmap(Bitmap bm) {
  
          super.setImageBitmap(bm);
  
          if (bm != null) {
  
              bmWidth = bm.getWidth();
  
              bmHeight = bm.getHeight();
  
          }
  
      }
  
      public void setMaxZoom(float x) {
  
          maxScale = x;
  
      }
  
      private class ScaleListener extends
              ScaleGestureDetector.SimpleOnScaleGestureListener {
  
          @Override
          public boolean onScaleBegin(ScaleGestureDetector detector) {
  
              mode = ZOOM;
  
              return true;
  
          }
  
          @Override
          public boolean onScale(ScaleGestureDetector detector) {
  
              float mScaleFactor = detector.getScaleFactor();
  
              float origScale = saveScale;
  
              saveScale *= mScaleFactor;
  
              if (saveScale &gt; maxScale) {
  
                  saveScale = maxScale;
  
                  mScaleFactor = maxScale / origScale;
  
              } else if (saveScale &lt; minScale) {
  
                  saveScale = minScale;
  
                  mScaleFactor = minScale / origScale;
  
              }
  
              right = width * saveScale - width
                      - (2 * redundantXSpace * saveScale);
  
              bottom = height * saveScale - height
                      - (2 * redundantYSpace * saveScale);
  
              // mPosX = mPosX + right / saveScale;
  
              // mPosY = mPosY + bottom / saveScale;
  
              if (origWidth * saveScale &lt;= width
                      || origHeight * saveScale &lt;= height) {
  
                  float xMove = 0, yMove = 0;
  
                  matrix.postScale(mScaleFactor, mScaleFactor, width / 2,
                          height / 2);
  
                  if (mScaleFactor &lt; 1) {
  
                      matrix.getValues(m);
  
                      float x = m[Matrix.MTRANS_X];
  
                      float y = m[Matrix.MTRANS_Y];
  
                      if (mScaleFactor &lt; 1) {
  
                          if (Math.round(origWidth * saveScale) &lt; width) {
  
                              if (y &lt; -bottom) {
  
                                  matrix.postTranslate(0, -(y + bottom));
  
                                  xMove = 0;
  
                                  yMove = -(y + bottom);
  
                              } else if (y &gt; 0) {
  
                                  matrix.postTranslate(0, -y);
  
                                  xMove = 0;
  
                                  yMove = -y;
  
                              }
  
                          } else {
  
                              if (x &lt; -right) {
  
                                  matrix.postTranslate(-(x + right), 0);
  
                                  xMove = -(x + right);
  
                                  yMove = 0;
  
                              } else if (x &gt; 0) {
  
                                  matrix.postTranslate(-x, 0);
  
                                  xMove = -(x + right);
  
                                  yMove = 0;
  
                              }
  
                          }
  
                          Log.i("onScale", "mPosX " + mPosX + " mPosX " + mPosX);
  
                      }
  
                  }
  
              } else {
  
                  float xMove = 0, yMove = 0;
  
                  matrix.postScale(mScaleFactor, mScaleFactor,
                          detector.getFocusX(), detector.getFocusY());
  
                  matrix.getValues(m);
  
                  float x = m[Matrix.MTRANS_X];
  
                  float y = m[Matrix.MTRANS_Y];
  
                  if (mScaleFactor &lt; 1) {
  
                      if (x &lt; -right) {
  
                          matrix.postTranslate(-(x + right), 0);
  
                          xMove = -(x + right);
  
                          yMove = 0;
  
                      } else if (x &gt; 0) {
  
                          matrix.postTranslate(-x, 0);
  
                          xMove = -x;
  
                          yMove = 0;
  
                      }
  
                      if (y &lt; -bottom) {
  
                          matrix.postTranslate(0, -(y + bottom));
  
                          xMove = 0;
  
                          yMove = -(y + bottom);
  
                      } else if (y &gt; 0) {
  
                          matrix.postTranslate(0, -y);
  
                          xMove = 0;
  
                          yMove = -y;
  
                      }
  
                  }
  
                  Log.i("onScale", "mPosX " + mPosX + " mPosX " + mPosX);
  
              }
  
              return true;
  
          }
  
      }
  
      @Override
      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  
          if (!isCheckLoadImage) {
  
              width = MeasureSpec.getSize(widthMeasureSpec);
  
              height = MeasureSpec.getSize(heightMeasureSpec);
  
              // Fit to screen.
  
              float scale;
  
              float scaleX = (float) width / (float) bmWidth;
  
              float scaleY = (float) height / (float) bmHeight;
  
              scale = Math.min(scaleX, scaleY);
  
              matrix.setScale(scale, scale);
  
              setImageMatrix(matrix);
  
              saveScale = 1f;
  
              // Center the image
  
              redundantYSpace = (float) height - (scale * (float) bmHeight);
  
              redundantXSpace = (float) width - (scale * (float) bmWidth);
  
              redundantYSpace /= (float) 2;
  
              redundantXSpace /= (float) 2;
  
              matrix.postTranslate(redundantXSpace, redundantYSpace);
  
              origWidth = width - 2 * redundantXSpace;
  
              origHeight = height - 2 * redundantYSpace;
  
              right = width * saveScale - width
                      - (2 * redundantXSpace * saveScale);
  
              bottom = height * saveScale - height
                      - (2 * redundantYSpace * saveScale);
  
              setImageMatrix(matrix);
  
          }
  
          super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  
      }
  
  }
  </code></pre>