首页 > 系统 > Android > 正文

Android手势滑动实现ImageView缩放图片大小

2020-04-11 10:49:18
字体:
来源:转载
供稿:网友

本文推出了两种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);  }}

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表