Android之實現手勢縮放imageview中的圖片

轉自:http://blog.csdn.net/way_ping_li/article/details/8477786

方法一:

將以下代碼寫到MulitPointTouchListener.java中,然後對你相應的圖片進行OnTouchListener。
例如:imageView.setOnTouchListener(new MulitPointTouchListener ());

在xml中要將ImageView的縮放格式改成Matrix

例如:android:scaleType="matrix"

這樣就可以實現圖片的縮放了

 

下面是MulitPointTouchListener.java代碼:

[java] view plaincopy
  1. public class MulitPointTouchListener implements OnTouchListener {     
  2.         private static final String TAG = "Touch";     
  3.         // These matrices will be used to move and zoom image     
  4.         Matrix matrix = new Matrix();     
  5.         Matrix savedMatrix = new Matrix();     
  6.     
  7.         // We can be in one of these 3 states     
  8.         static final int NONE = 0;     
  9.         static final int DRAG = 1;     
  10.         static final int ZOOM = 2;     
  11.         int mode = NONE;     
  12.     
  13.         // Remember some things for zooming     
  14.         PointF start = new PointF();     
  15.         PointF mid = new PointF();     
  16.         float oldDist = 1f;     
  17.     
  18.         @Override    
  19.         public boolean onTouch(View v, MotionEvent event) {     
  20.     
  21.                 ImageView view = (ImageView) v;     
  22.                 // Log.e("view_width",     
  23.                 // view.getImageMatrix()..toString()+"*"+v.getWidth());     
  24.                 // Dump touch event to log     
  25.                 dumpEvent(event);     
  26.     
  27.                 // Handle touch events here...     
  28.                 switch (event.getAction() & MotionEvent.ACTION_MASK) {     
  29.                 case MotionEvent.ACTION_DOWN:     
  30.     
  31.                         matrix.set(view.getImageMatrix());     
  32.                         savedMatrix.set(matrix);     
  33.                         start.set(event.getX(), event.getY());     
  34.                         //Log.d(TAG, "mode=DRAG");     
  35.                         mode = DRAG;     
  36.     
  37.                             
  38.                         //Log.d(TAG, "mode=NONE");     
  39.                         break;     
  40.                 case MotionEvent.ACTION_POINTER_DOWN:     
  41.                         oldDist = spacing(event);     
  42.                         //Log.d(TAG, "oldDist=" + oldDist);     
  43.                         if (oldDist > 10f) {     
  44.                                 savedMatrix.set(matrix);     
  45.                                 midPoint(mid, event);     
  46.                                 mode = ZOOM;     
  47.                                 //Log.d(TAG, "mode=ZOOM");     
  48.                         }     
  49.                         break;     
  50.                 case MotionEvent.ACTION_UP:     
  51.                 case MotionEvent.ACTION_POINTER_UP:     
  52.                         mode = NONE;     
  53.                         //Log.e("view.getWidth", view.getWidth() + "");     
  54.                         //Log.e("view.getHeight", view.getHeight() + "");     
  55.     
  56.                         break;     
  57.                 case MotionEvent.ACTION_MOVE:     
  58.                         if (mode == DRAG) {     
  59.                                 // ...     
  60.                                 matrix.set(savedMatrix);     
  61.                                 matrix.postTranslate(event.getX() - start.x, event.getY()     
  62.                                                 - start.y);     
  63.                         } else if (mode == ZOOM) {     
  64.                                 float newDist = spacing(event);     
  65.                                 //Log.d(TAG, "newDist=" + newDist);     
  66.                                 if (newDist > 10f) {     
  67.                                         matrix.set(savedMatrix);     
  68.                                         float scale = newDist / oldDist;     
  69.                                         matrix.postScale(scale, scale, mid.x, mid.y);     
  70.                                 }     
  71.                         }     
  72.                         break;     
  73.                 }     
  74.     
  75.                 view.setImageMatrix(matrix);     
  76.                 return true// indicate event was handled     
  77.         }     
  78.     
  79.         private void dumpEvent(MotionEvent event) {     
  80.                 String names[] = { "DOWN""UP""MOVE""CANCEL""OUTSIDE",     
  81.                                 "POINTER_DOWN""POINTER_UP""7?""8?""9?" };     
  82.                 StringBuilder sb = new StringBuilder();     
  83.                 int action = event.getAction();     
  84.                 int actionCode = action & MotionEvent.ACTION_MASK;     
  85.                 sb.append("event ACTION_").append(names[actionCode]);     
  86.                 if (actionCode == MotionEvent.ACTION_POINTER_DOWN     
  87.                                 || actionCode == MotionEvent.ACTION_POINTER_UP) {     
  88.                         sb.append("(pid ").append(     
  89.                                         action >> MotionEvent.ACTION_POINTER_ID_SHIFT);     
  90.                         sb.append(")");     
  91.                 }     
  92.                 sb.append("[");     
  93.                 for (int i = 0; i < event.getPointerCount(); i++) {     
  94.                         sb.append("#").append(i);     
  95.                         sb.append("(pid ").append(event.getPointerId(i));     
  96.                         sb.append(")=").append((int) event.getX(i));     
  97.                         sb.append(",").append((int) event.getY(i));     
  98.                         if (i + 1 < event.getPointerCount())     
  99.                                 sb.append(";");     
  100.                 }     
  101.                 sb.append("]");     
  102.                 //Log.d(TAG, sb.toString());     
  103.         }     
  104.     
  105.             
  106.         private float spacing(MotionEvent event) {     
  107.                 float x = event.getX(0) - event.getX(1);     
  108.                 float y = event.getY(0) - event.getY(1);     
  109.                 return FloatMath.sqrt(x * x + y * y);     
  110.         }     
  111.     
  112.             
  113.         private void midPoint(PointF point, MotionEvent event) {     
  114.                 float x = event.getX(0) + event.getX(1);     
  115.                 float y = event.getY(0) + event.getY(1);     
  116.                 point.set(x / 2, y / 2);     
  117.         }     
  118. }    


方法二:自定義一個ImageView,例如TouchImageView:

[java] view plaincopy
  1. import android.content.Context;  
  2. import android.graphics.Matrix;  
  3. import android.graphics.PointF;  
  4. import android.graphics.drawable.Drawable;  
  5. import android.util.AttributeSet;  
  6. import android.util.Log;  
  7. import android.view.MotionEvent;  
  8. import android.view.ScaleGestureDetector;  
  9. import android.view.View;  
  10. import android.widget.ImageView;  
  11.   
  12. public class TouchImageView extends ImageView {  
  13.   
  14.     Matrix matrix;  
  15.   
  16.     // We can be in one of these 3 states  
  17.     static final int NONE = 0;  
  18.     static final int DRAG = 1;  
  19.     static final int ZOOM = 2;  
  20.     int mode = NONE;  
  21.   
  22.     // Remember some things for zooming  
  23.     PointF last = new PointF();  
  24.     PointF start = new PointF();  
  25.     float minScale = 1f;  
  26.     float maxScale = 3f;  
  27.     float[] m;  
  28.   
  29.   
  30.     int viewWidth, viewHeight;  
  31.     static final int CLICK = 3;  
  32.     float saveScale = 1f;  
  33.     protected float origWidth, origHeight;  
  34.     int oldMeasuredWidth, oldMeasuredHeight;  
  35.   
  36.   
  37.     ScaleGestureDetector mScaleDetector;  
  38.   
  39.     Context context;  
  40.   
  41.     public TouchImageView(Context context) {  
  42.         super(context);  
  43.         sharedConstructing(context);  
  44.     }  
  45.   
  46.     public TouchImageView(Context context, AttributeSet attrs) {  
  47.         super(context, attrs);  
  48.         sharedConstructing(context);  
  49.     }  
  50.       
  51.     private void sharedConstructing(Context context) {  
  52.         super.setClickable(true);  
  53.         this.context = context;  
  54.         mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());  
  55.         matrix = new Matrix();  
  56.         m = new float[9];  
  57.         setImageMatrix(matrix);  
  58.         setScaleType(ScaleType.MATRIX);  
  59.   
  60.         setOnTouchListener(new OnTouchListener() {  
  61.   
  62.             @Override  
  63.             public boolean onTouch(View v, MotionEvent event) {  
  64.                 mScaleDetector.onTouchEvent(event);  
  65.                 PointF curr = new PointF(event.getX(), event.getY());  
  66.   
  67.                 switch (event.getAction()) {  
  68.                     case MotionEvent.ACTION_DOWN:  
  69.                         last.set(curr);  
  70.                         start.set(last);  
  71.                         mode = DRAG;  
  72.                         break;  
  73.                           
  74.                     case MotionEvent.ACTION_MOVE:  
  75.                         if (mode == DRAG) {  
  76.                             float deltaX = curr.x - last.x;  
  77.                             float deltaY = curr.y - last.y;  
  78.                             float fixTransX = getFixDragTrans(deltaX, viewWidth, origWidth * saveScale);  
  79.                             float fixTransY = getFixDragTrans(deltaY, viewHeight, origHeight * saveScale);  
  80.                             matrix.postTranslate(fixTransX, fixTransY);  
  81.                             fixTrans();  
  82.                             last.set(curr.x, curr.y);  
  83.                         }  
  84.                         break;  
  85.   
  86.                     case MotionEvent.ACTION_UP:  
  87.                         mode = NONE;  
  88.                         int xDiff = (int) Math.abs(curr.x - start.x);  
  89.                         int yDiff = (int) Math.abs(curr.y - start.y);  
  90.                         if (xDiff < CLICK && yDiff < CLICK)  
  91.                             performClick();  
  92.                         break;  
  93.   
  94.                     case MotionEvent.ACTION_POINTER_UP:  
  95.                         mode = NONE;  
  96.                         break;  
  97.                 }  
  98.                   
  99.                 setImageMatrix(matrix);  
  100.                 invalidate();  
  101.                 return true// indicate event was handled  
  102.             }  
  103.   
  104.         });  
  105.     }  
  106.   
  107.     public void setMaxZoom(float x) {  
  108.         maxScale = x;  
  109.     }  
  110.   
  111.     private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {  
  112.         @Override  
  113.         public boolean onScaleBegin(ScaleGestureDetector detector) {  
  114.             mode = ZOOM;  
  115.             return true;  
  116.         }  
  117.   
  118.         @Override  
  119.         public boolean onScale(ScaleGestureDetector detector) {  
  120.             float mScaleFactor = detector.getScaleFactor();  
  121.             float origScale = saveScale;  
  122.             saveScale *= mScaleFactor;  
  123.             if (saveScale > maxScale) {  
  124.                 saveScale = maxScale;  
  125.                 mScaleFactor = maxScale / origScale;  
  126.             } else if (saveScale < minScale) {  
  127.                 saveScale = minScale;  
  128.                 mScaleFactor = minScale / origScale;  
  129.             }  
  130.   
  131.             if (origWidth * saveScale <= viewWidth || origHeight * saveScale <= viewHeight)  
  132.                 matrix.postScale(mScaleFactor, mScaleFactor, viewWidth / 2, viewHeight / 2);  
  133.             else  
  134.                 matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY());  
  135.   
  136.             fixTrans();  
  137.             return true;  
  138.         }  
  139.     }  
  140.   
  141.     void fixTrans() {  
  142.         matrix.getValues(m);  
  143.         float transX = m[Matrix.MTRANS_X];  
  144.         float transY = m[Matrix.MTRANS_Y];  
  145.           
  146.         float fixTransX = getFixTrans(transX, viewWidth, origWidth * saveScale);  
  147.         float fixTransY = getFixTrans(transY, viewHeight, origHeight * saveScale);  
  148.   
  149.         if (fixTransX != 0 || fixTransY != 0)  
  150.             matrix.postTranslate(fixTransX, fixTransY);  
  151.     }  
  152.   
  153.     float getFixTrans(float trans, float viewSize, float contentSize) {  
  154.         float minTrans, maxTrans;  
  155.   
  156.         if (contentSize <= viewSize) {  
  157.             minTrans = 0;  
  158.             maxTrans = viewSize - contentSize;  
  159.         } else {  
  160.             minTrans = viewSize - contentSize;  
  161.             maxTrans = 0;  
  162.         }  
  163.   
  164.         if (trans < minTrans)  
  165.             return -trans + minTrans;  
  166.         if (trans > maxTrans)  
  167.             return -trans + maxTrans;  
  168.         return 0;  
  169.     }  
  170.       
  171.     float getFixDragTrans(float delta, float viewSize, float contentSize) {  
  172.         if (contentSize <= viewSize) {  
  173.             return 0;  
  174.         }  
  175.         return delta;  
  176.     }  
  177.   
  178.     @Override  
  179.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  180.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
  181.         viewWidth = MeasureSpec.getSize(widthMeasureSpec);  
  182.         viewHeight = MeasureSpec.getSize(heightMeasureSpec);  
  183.           
  184.         //  
  185.         // Rescales image on rotation  
  186.         //  
  187.         if (oldMeasuredHeight == viewWidth && oldMeasuredHeight == viewHeight  
  188.                 || viewWidth == 0 || viewHeight == 0)  
  189.             return;  
  190.         oldMeasuredHeight = viewHeight;  
  191.         oldMeasuredWidth = viewWidth;  
  192.   
  193.         if (saveScale == 1) {  
  194.             //Fit to screen.  
  195.             float scale;  
  196.   
  197.             Drawable drawable = getDrawable();  
  198.             if (drawable == null || drawable.getIntrinsicWidth() == 0 || drawable.getIntrinsicHeight() == 0)  
  199.                 return;  
  200.             int bmWidth = drawable.getIntrinsicWidth();  
  201.             int bmHeight = drawable.getIntrinsicHeight();  
  202.               
  203.             Log.d("bmSize""bmWidth: " + bmWidth + " bmHeight : " + bmHeight);  
  204.   
  205.             float scaleX = (float) viewWidth / (float) bmWidth;  
  206.             float scaleY = (float) viewHeight / (float) bmHeight;  
  207.             scale = Math.min(scaleX, scaleY);  
  208.             matrix.setScale(scale, scale);  
  209.   
  210.             // Center the image  
  211.             float redundantYSpace = (float) viewHeight - (scale * (float) bmHeight);  
  212.             float redundantXSpace = (float) viewWidth - (scale * (float) bmWidth);  
  213.             redundantYSpace /= (float2;  
  214.             redundantXSpace /= (float2;  
  215.   
  216.             matrix.postTranslate(redundantXSpace, redundantYSpace);  
  217.   
  218.             origWidth = viewWidth - 2 * redundantXSpace;  
  219.             origHeight = viewHeight - 2 * redundantYSpace;  
  220.             setImageMatrix(matrix);  
  221.         }  
  222.         fixTrans();  
  223.     }  
  224. }  

然後在我們的Activity中就可以直接使用了:

[java] view plaincopy
  1. public class TouchImageViewActivity extends Activity {  
  2.     /** Called when the activity is first created. */  
  3.     @Override  
  4.     public void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         setContentView(R.layout.main);  
  7.         TouchImageView img = (TouchImageView) findViewById(R.id.snoop);  
  8.         img.setImageResource(R.drawable.snoopy);  
  9.         img.setMaxZoom(4f);  
  10.     }  
  11. }  

發佈了22 篇原創文章 · 獲贊 3 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章