Welcome 微信登录

首页 / 移动开发 / Android / Android手势滑动实现ImageView缩放图片大小

本文推出了两种Android手势实现ImageView缩放图片大小的方法,分享给大家供大家参考,具体内容如下
方法一:
将以下代码写到MulitPointTouchListener.java中,然后对你相应的图片进行OnTouchListener。
例如:imageView.setOnTouchListener(new MulitPointTouchListener ());
在xml中要将ImageView的缩放格式改成Matrix
例如:android:scaleType="matrix"
这样就可以实现图片的缩放了
下面是MulitPointTouchListener.java代码:

public class MulitPointTouchListener implements OnTouchListener {private static final String TAG = "Touch";// These matrices will be used to move and zoom imageMatrix matrix = new Matrix();Matrix savedMatrix = new Matrix(); // We can be in one of these 3 statesstatic final int NONE = 0;static final int DRAG = 1;static final int ZOOM = 2;int mode = NONE; // Remember some things for zoomingPointF start = new PointF();PointF mid = new PointF();float oldDist = 1f; @Override public boolean onTouch(View v, MotionEvent event) { ImageView view = (ImageView) v;// Log.e("view_width",// view.getImageMatrix()..toString()+"*"+v.getWidth());// Dump touch event to logdumpEvent(event); // Handle touch events here...switch (event.getAction() & MotionEvent.ACTION_MASK) {case MotionEvent.ACTION_DOWN: matrix.set(view.getImageMatrix());savedMatrix.set(matrix);start.set(event.getX(), event.getY());//Log.d(TAG, "mode=DRAG");mode = DRAG;//Log.d(TAG, "mode=NONE");break;case MotionEvent.ACTION_POINTER_DOWN:oldDist = spacing(event);//Log.d(TAG, "oldDist=" + oldDist);if (oldDist > 10f) {savedMatrix.set(matrix);midPoint(mid, event);mode = ZOOM;//Log.d(TAG, "mode=ZOOM");}break;case MotionEvent.ACTION_UP:case MotionEvent.ACTION_POINTER_UP:mode = NONE;//Log.e("view.getWidth", view.getWidth() + "");//Log.e("view.getHeight", view.getHeight() + ""); 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);//Log.d(TAG, "newDist=" + newDist);if (newDist > 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} 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 & 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 >> MotionEvent.ACTION_POINTER_ID_SHIFT);sb.append(")");}sb.append("[");for (int i = 0; i < 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 < event.getPointerCount())sb.append(";");}sb.append("]");//Log.d(TAG, sb.toString());}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);}} 

方法二:自定义一个ImageView,例如TouchImageView:

import android.content.Context;import android.graphics.Matrix;import android.graphics.PointF;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.ScaleGestureDetector;import android.view.View;import android.widget.ImageView;public class TouchImageView extends ImageView {Matrix matrix;// We can be in one of these 3 statesstatic final int NONE = 0;static final int DRAG = 1;static final int ZOOM = 2;int mode = NONE;// Remember some things for zoomingPointF last = new PointF();PointF start = new PointF();float minScale = 1f;float maxScale = 3f;float[] m;int viewWidth, viewHeight;static final int CLICK = 3;float saveScale = 1f;protected float origWidth, origHeight;int oldMeasuredWidth, oldMeasuredHeight;ScaleGestureDetector mScaleDetector;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) {super.setClickable(true);this.context = context;mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());matrix = new Matrix();m = new float[9];setImageMatrix(matrix);setScaleType(ScaleType.MATRIX);setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {mScaleDetector.onTouchEvent(event);PointF curr = new PointF(event.getX(), event.getY());switch (event.getAction()) {case MotionEvent.ACTION_DOWN: last.set(curr);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 fixTransX = getFixDragTrans(deltaX, viewWidth, origWidth * saveScale);float fixTransY = getFixDragTrans(deltaY, viewHeight, origHeight * saveScale);matrix.postTranslate(fixTransX, fixTransY);fixTrans();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 < CLICK && yDiff < CLICK)performClick();break;case MotionEvent.ACTION_POINTER_UP:mode = NONE;break;}setImageMatrix(matrix);invalidate();return true; // indicate event was handled}});}public void setMaxZoom(float x) {maxScale = x;}private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {@Overridepublic boolean onScaleBegin(ScaleGestureDetector detector) {mode = ZOOM;return true;}@Overridepublic boolean onScale(ScaleGestureDetector detector) {float mScaleFactor = detector.getScaleFactor();float origScale = saveScale;saveScale *= mScaleFactor;if (saveScale > maxScale) {saveScale = maxScale;mScaleFactor = maxScale / origScale;} else if (saveScale < minScale) {saveScale = minScale;mScaleFactor = minScale / origScale;}if (origWidth * saveScale <= viewWidth || origHeight * saveScale <= viewHeight)matrix.postScale(mScaleFactor, mScaleFactor, viewWidth / 2, viewHeight / 2);elsematrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY());fixTrans();return true;}}void fixTrans() {matrix.getValues(m);float transX = m[Matrix.MTRANS_X];float transY = m[Matrix.MTRANS_Y];float fixTransX = getFixTrans(transX, viewWidth, origWidth * saveScale);float fixTransY = getFixTrans(transY, viewHeight, origHeight * saveScale);if (fixTransX != 0 || fixTransY != 0)matrix.postTranslate(fixTransX, fixTransY);}float getFixTrans(float trans, float viewSize, float contentSize) {float minTrans, maxTrans;if (contentSize <= viewSize) {minTrans = 0;maxTrans = viewSize - contentSize;} else {minTrans = viewSize - contentSize;maxTrans = 0;}if (trans < minTrans)return -trans + minTrans;if (trans > maxTrans)return -trans + maxTrans;return 0;}float getFixDragTrans(float delta, float viewSize, float contentSize) {if (contentSize <= viewSize) {return 0;}return delta;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);viewWidth = MeasureSpec.getSize(widthMeasureSpec);viewHeight = MeasureSpec.getSize(heightMeasureSpec);//// Rescales image on rotation//if (oldMeasuredHeight == viewWidth && oldMeasuredHeight == viewHeight|| viewWidth == 0 || viewHeight == 0)return;oldMeasuredHeight = viewHeight;oldMeasuredWidth = viewWidth;if (saveScale == 1) {//Fit to screen.float scale;Drawable drawable = getDrawable();if (drawable == null || drawable.getIntrinsicWidth() == 0 || drawable.getIntrinsicHeight() == 0)return;int bmWidth = drawable.getIntrinsicWidth();int bmHeight = drawable.getIntrinsicHeight();Log.d("bmSize", "bmWidth: " + bmWidth + " bmHeight : " + bmHeight);float scaleX = (float) viewWidth / (float) bmWidth;float scaleY = (float) viewHeight / (float) bmHeight;scale = Math.min(scaleX, scaleY);matrix.setScale(scale, scale);// Center the imagefloat redundantYSpace = (float) viewHeight - (scale * (float) bmHeight);float redundantXSpace = (float) viewWidth - (scale * (float) bmWidth);redundantYSpace /= (float) 2;redundantXSpace /= (float) 2;matrix.postTranslate(redundantXSpace, redundantYSpace);origWidth = viewWidth - 2 * redundantXSpace;origHeight = viewHeight - 2 * redundantYSpace;setImageMatrix(matrix);}fixTrans();}}

然后在我们的Activity中就可以直接使用了:

public class TouchImageViewActivity extends Activity {/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);TouchImageView img = (TouchImageView) findViewById(R.id.snoop);img.setImageResource(R.drawable.snoopy);img.setMaxZoom(4f);}}