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 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; 
    // Log.e("view_width", 
    // view.getImageMatrix()..toString()+"*"+v.getWidth()); 
    // Dump touch event to log 
    dumpEvent(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 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;


 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() {

   @Override
   public 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 {
  @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 > 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);
   else
    matrix.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;
 }

 @Override
 protected 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 image
   float 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. */
 @Override
 public 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);
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。