title: Implementing Double tap into TouchImageView - dragging picture doesn't work now
body: <p>I have a problem. I've used TouchImageView code from here - <a href="https://github.com/MikeOrtiz/TouchImageView" rel="nofollow">https://github.com/MikeOrtiz/TouchImageView</a> . I have implemented into it double tapping functionality. It works fine, but now I can't drag my image when it is zoomed in. Zooming by gestures (pinch zoom) works fine, I just can't navigate on zoomed image. I don't know why. Here is my actual code:</p>
  
  <pre><code>        package com.example.testy;
  
      import android.content.Context;
      import android.graphics.Bitmap;
      import android.graphics.Matrix;
      import android.graphics.PointF;
      import android.util.AttributeSet;
      import android.view.GestureDetector;
      import android.view.GestureDetector.SimpleOnGestureListener;
      import android.view.MotionEvent;
      import android.view.ScaleGestureDetector;
      import android.view.View;
      import android.widget.ImageView;
  
      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;
          int mode = NONE;
  
          // Remember some things for zooming
          PointF last = new PointF();
          PointF start = new PointF();
          float minScale = 1f;
          float maxScale = 3f;
          float[] m;
  
          float redundantXSpace, redundantYSpace;
  
          float width, height;
          static final int CLICK = 3;
          float saveScale = 1f;
          float right, bottom, origWidth, origHeight, bmWidth, bmHeight;
  
          ScaleGestureDetector mScaleDetector;
          GestureDetector gestureDetector;
          Context context;
  
          public TouchImageView(Context context) {
              super(context);
              sharedConstructing(context);
          }
  
          public TouchImageView(Context context, AttributeSet attrs) {
              super(context, attrs);
              sharedConstructing(context);
          }
  
          private void sharedConstructing(Context context) {
              gestureDetector = new GestureDetector(new DoubleTapGestureListener());
              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) {
                      if (gestureDetector.onTouchEvent(event)) {
                          return true; // podwojne klikniecie i koniec imprezy
                      }
                      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;
                          break;
                      case MotionEvent.ACTION_MOVE:
                          if (mode == DRAG) {
                              float deltaX = curr.x - last.x;
                              float deltaY = curr.y - last.y;
                              float scaleWidth = Math.round(origWidth * saveScale);
                              float 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)
                              performClick();
                          break;
  
                      case MotionEvent.ACTION_POINTER_UP:
                          mode = NONE;
                          break;
                      }
                      setImageMatrix(matrix);
                      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;
          }
  
          public boolean canScrollHorizontally(int direction) { //used to cooparate with ViewPager
              matrix.getValues(m);
              float x = Math.abs(m[Matrix.MTRANS_X]);
              float scaleWidth = Math.round(origWidth * saveScale);
  
              if (scaleWidth &lt; width) {
                  return false;
  
              } else {
                  if (x - direction &lt;= 0)
                      return false; // reach left edge
                  else if (x + width - direction &gt;= scaleWidth)
                      return false; // reach right edge
  
                  return true;
              }
          }
  
          @Override
          protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
              super.onMeasure(widthMeasureSpec, heightMeasureSpec);
              width = MeasureSpec.getSize(widthMeasureSpec);
              height = MeasureSpec.getSize(heightMeasureSpec);
              // Fit to screen.
              float scale;
              float scaleX = width / bmWidth;
              float scaleY = height / bmHeight;
              scale = Math.min(scaleX, scaleY);
              matrix.setScale(scale, scale);
              setImageMatrix(matrix);
              saveScale = 1f;
  
              // Center the image
              redundantYSpace = height - (scale * bmHeight);
              redundantXSpace = width - (scale * bmWidth);
              redundantYSpace /= 2;
              redundantXSpace /= 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);
          }
  
          public boolean isZoomed() {
              return saveScale &gt; minScale;
          }
  
          public void zoomIn() {
  
              System.out.println("Zoom in!");
  
              saveScale = maxScale;
              matrix.setScale(saveScale, saveScale);
              setImageMatrix(matrix);
              invalidate();
          }
  
          public void zoomOut() {
  
              saveScale = minScale;
              matrix.setScale(saveScale, saveScale);
              setImageMatrix(matrix);
              invalidate();
  
              System.out.println("Zoom out!");
          }
  
          private class DoubleTapGestureListener extends SimpleOnGestureListener {
  
              @Override
              public boolean onDown(MotionEvent e) {
                  return true;
              }
  
              // event when double tap occurs
              @Override
              public boolean onDoubleTap(MotionEvent e) {
                  float x = e.getX();
                  float y = e.getY();
  
                  if (isZoomed()) {
                      zoomOut();
                  } else {
                      zoomIn();
                  }
                  return true;
              }
  
          }
  
          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);
                  if (origWidth * saveScale &lt;= width
                          || origHeight * saveScale &lt;= height) {
                      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));
                                  else if (y &gt; 0)
                                      matrix.postTranslate(0, -y);
                              } else {
                                  if (x &lt; -right)
                                      matrix.postTranslate(-(x + right), 0);
                                  else if (x &gt; 0)
                                      matrix.postTranslate(-x, 0);
                              }
                          }
                      }
                  } else {
                      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);
                          else if (x &gt; 0)
                              matrix.postTranslate(-x, 0);
                          if (y &lt; -bottom)
                              matrix.postTranslate(0, -(y + bottom));
                          else if (y &gt; 0)
                              matrix.postTranslate(0, -y);
                      }
                  }
                  return true;
  
              }
      }
  }
  </code></pre>
  
  <p>Do you have any problems what can be wrong?</p>
  
  <p>Thank you!</p>