title: Move/drag/zoom an imageview in Android
body: <p>I am developing an app which takes a picture from camera and then applies an imageview on top of it.
  Now, I need to move and resize (with pinch) the imageview above the captured picture.</p>
  
  <p>First I've implemented a simple drag behavior which worked well (I cannot use the drag event since min sdk level), but problems have came when I tried to add a pinch-to-zoom action too.</p>
  
  <p>Right now I've tried several solutions found on stackoverflow, but none of them has worked for my scenario.</p>
  
  <p>Here is the custom view that I'm using (found after some searchs)
  <a href="https://dl.dropboxusercontent.com/u/230145/PanZoomView.java" rel="nofollow">https://dl.dropboxusercontent.com/u/230145/PanZoomView.java</a></p>
  
  <p>but it has a weird behavior since when I try to do a zoom or drag it, the object gets crazy  on the screen.</p>
  
  <p>Anyone has an idea or solution for this?</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>Finally I've solved with the following code:</p>
  
  <p>Code from Java Class:</p>
  
  <pre><code>private ImageView mOrologio;
  private FrameLayout mPhotoBox;
  Matrix matrix = new Matrix();
  Matrix savedMatrix = 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 start = new PointF();
  PointF mid = new PointF();
  float oldDist = 1f;
  
  ...
  ...
  
  private void bindViews(View rootView) {
      ...
      mPhotoBox = (FrameLayout) rootView.findViewById(R.id.fotoBox);
  
      mOrologio = (ImageView) rootView.findViewById(R.id.imgOrologio);
      mOrologio.setOnTouchListener(this);
      ...
  }
  
  private float spacing(MotionEvent event) {
      float x = event.getX(0) - event.getX(1);
      float y = event.getY(0) - event.getY(1);
      return FloatMath.sqrt(x * x + y * y);
  }
  
  private void midPoint(PointF point, MotionEvent event) {
      float x = event.getX(0) + event.getX(1);
      float y = event.getY(0) + event.getY(1);
      point.set(x / 2, y / 2);
  }
  
  @Override
  public boolean onTouch(View v, MotionEvent event) {
      ImageView view = (ImageView) v;
  
      switch (event.getAction() &amp; MotionEvent.ACTION_MASK) {
          case MotionEvent.ACTION_DOWN:
              savedMatrix.set(matrix);
              start.set(event.getX(), event.getY());
              mode = DRAG;
              break;
          case MotionEvent.ACTION_POINTER_DOWN:
              oldDist = spacing(event);
              if (oldDist &gt; 10f) {
                  savedMatrix.set(matrix);
                  midPoint(mid, event);
                  mode = ZOOM;
              }
              break;
          case MotionEvent.ACTION_UP:
          case MotionEvent.ACTION_POINTER_UP:
              mode = NONE;
              break;
          case MotionEvent.ACTION_MOVE:
              if (mode == DRAG) {
                  // ...
                  matrix.set(savedMatrix);
                  matrix.postTranslate(event.getX() - start.x,
                          event.getY() - start.y);
              }
              else if (mode == ZOOM) {
                  float newDist = spacing(event);
                  if (newDist &gt; 10f) {
                      matrix.set(savedMatrix);
                      float scale = newDist / oldDist;
                      matrix.postScale(scale, scale, mid.x, mid.y);
                  }
              }
              break;
      }
  
      view.setImageMatrix(matrix);
      return true; // indicate event was handled
    }
  }
  </code></pre>
  
  <p>Code from XML Layout:</p>
  
  <pre><code>&lt;FrameLayout
          android:id="@+id/fotoBox"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          android:layout_above="@+id/prev_list" &gt;
  
          &lt;ImageView
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:id="@+id/imgOrologio"
              android:scaleType="matrix"
              android:layout_gravity="right|center_vertical" /&gt;
  
      &lt;/FrameLayout&gt;
  </code></pre>
  
  <p>So basically I've learned this lesson:</p>
  
  <ul>
  <li>FrameLayout is needed as rootView if you want to move/zoom your ImageView</li>
  <li>If you want to move/zoom an ImageView like in my scenario you don't need to override the ImageView class but only handle the touch events.</li>
  </ul>
  
  <p>Thank you all for replies and hope this solution will be usefull =)</p>