title: Pinch for ImageView
body: <p>I have imageView. I need to use pinch for imageView. I referred some documents. But everything used doubleTap. When use doubleTap zoomIn and ZoomOut. I dn't want doubltTap ZoomIn and out. I need to use fingers for pinch. I used OnTouch for imageView moving.</p>
  
  <p>code:</p>
  
  <p>Touch class:</p>
  
  <pre><code>package com.example.blogactivity;
  
  import android.graphics.Matrix;  
  import android.graphics.PointF;  
  import android.util.FloatMath;  
  import android.view.MotionEvent;  
  import android.view.View;  
  import android.view.View.OnTouchListener;  
  import android.widget.ImageView;
  
  public class Touch implements OnTouchListener{
  
      // These matrices will be used to move and zoom image  
       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;  
  
  
       @Override  
       public boolean onTouch(View v, MotionEvent event) {  
        ImageView view = (ImageView) v;  
        // Dump touch event to log  
        dumpEvent(event);  
  
        // Handle touch events here...  
        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  
       }  
  
       /** Show an event in the LogCat view, for debugging */  
       private void dumpEvent(MotionEvent event) {  
        String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",  
          "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };  
        StringBuilder sb = new StringBuilder();  
        int action = event.getAction();  
        int actionCode = action &amp; MotionEvent.ACTION_MASK;  
        sb.append("event ACTION_").append(names[actionCode]);  
        if (actionCode == MotionEvent.ACTION_POINTER_DOWN  
          || actionCode == MotionEvent.ACTION_POINTER_UP) {  
         sb.append("(pid ").append(  
           action &gt;&gt; MotionEvent.ACTION_POINTER_ID_SHIFT);  
         sb.append(")");  
        }  
        sb.append("[");  
        for (int i = 0; i &lt; event.getPointerCount(); i++) {  
         sb.append("#").append(i);  
         sb.append("(pid ").append(event.getPointerId(i));  
         sb.append(")=").append((int) event.getX(i));  
         sb.append(",").append((int) event.getY(i));  
         if (i + 1 &lt; event.getPointerCount())  
          sb.append(";");  
        }  
        sb.append("]");  
       }  
  
  
  
       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);  
       }  
  
  
  }
  </code></pre>
  
  <p>MainActivity:</p>
  
  <pre><code>package com.example.blogactivity;
  
  import com.example.blogactivity.*;
  
  import android.app.Activity;
  import android.os.Bundle;
  import android.view.Menu;
  import android.widget.ImageView;
  
  public class BlogActivity extends Activity {
  
      ImageView image;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_blog);
  
          image=(ImageView)findViewById(R.id.imageView);
  
          image.setOnTouchListener(new Touch()); 
      }
  
      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
          // Inflate the menu; this adds items to the action bar if it is present.
          getMenuInflater().inflate(R.menu.blog, menu);
          return true;
      }
  
  }
  </code></pre>
  
  <p>xml:</p>
  
  <pre><code>&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:paddingBottom="@dimen/activity_vertical_margin"
      android:paddingLeft="@dimen/activity_horizontal_margin"
      android:paddingRight="@dimen/activity_horizontal_margin"
      android:paddingTop="@dimen/activity_vertical_margin"
      tools:context=".BlogActivity" &gt;
  
      &lt;ImageView android:id="@+id/imageView"  
         android:layout_width="match_parent"  
         android:layout_height="match_parent"  
         android:src="@drawable/butterfly"  
         android:scaleType="matrix"  
         android:adjustViewBounds="true"  
         android:layout_gravity="center" /&gt;  
  
  
  &lt;/RelativeLayout&gt;
  </code></pre>