html5中文学习网

您的位置: 首页 > android » 正文

Android实现手势控制ImageView图片大小_Android

[ ] 已经帮助:人解决问题

本文实例实现的主要功能是在ImageView中识别手势用以控制图片放大或缩小,具有一定的参考价值,分享给大家。ks4HTML5中文学习网 - HTML5先行者学习网

public class MatrixImageView extends ImageView {  private GestureDetector mGestureDetector;  private Matrix mMatrix = new Matrix();  private float mImageWidth;  private float mImageHeight;  private float mScale;  private OnMovingListener mMoveListener;  private OnSingleTapListener mSingleTapListener;  public MatrixImageView(Context context, AttributeSet attrs) {    super(context, attrs);    init();  }  public MatrixImageView(Context context) {    super(context, null);    init();  }  private void init() {    MatrixTouchListener listener = new MatrixTouchListener();    setOnTouchListener(listener);    mGestureDetector = new GestureDetector(getContext(),        new GestureListener(listener));    setBackgroundColor(Color.BLACK);    setScaleType(ScaleType.FIT_CENTER);  }  public void setOnMovingListener(OnMovingListener listener) {    mMoveListener = listener;  }  public void setOnSingleTapListener(OnSingleTapListener onSingleTapListener) {    this.mSingleTapListener = onSingleTapListener;  }  @Override  public void setImageBitmap(Bitmap bm) {    super.setImageBitmap(bm);    if (getWidth() == 0) {      ViewTreeObserver vto = getViewTreeObserver();      vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {        public boolean onPreDraw() {          initData();          MatrixImageView.this.getViewTreeObserver()              .removeOnPreDrawListener(this);          return true;        }      });    } else {      initData();    }  }  private void initData() {    mMatrix.set(getImageMatrix());    float[] values = new float[9];    mMatrix.getValues(values);    mImageWidth = getWidth() / values[Matrix.MSCALE_X];    mImageHeight = (getHeight() - values[Matrix.MTRANS_Y] * 2)        / values[Matrix.MSCALE_Y];    mScale = values[Matrix.MSCALE_X];  }  public class MatrixTouchListener implements OnTouchListener {    private static final int MODE_DRAG = 1;    private static final int MODE_ZOOM = 2;    private static final int MODE_UNABLE = 3;    private static final float MAX_SCALE = 6;    private static final float DOUBLE_CLICK_SACLE = 2;    private int mMode = 0;    private float mStartDis;    private Matrix mCurrentMatrix = new Matrix();    private boolean mLeftDragable;    private boolean mRightDragable;    private boolean mFirstMove = false;    private PointF mStartPoint = new PointF();    @Override    public boolean onTouch(View v, MotionEvent event) {      switch (event.getActionMasked()) {      case MotionEvent.ACTION_DOWN:        mMode = MODE_DRAG;        mStartPoint.set(event.getX(), event.getY());        isMatrixEnable();        startDrag();        checkDragable();        break;      case MotionEvent.ACTION_UP:      case MotionEvent.ACTION_CANCEL:        reSetMatrix();        stopDrag();        break;      case MotionEvent.ACTION_MOVE:        if (mMode == MODE_ZOOM) {          setZoomMatrix(event);        } else if (mMode == MODE_DRAG) {          setDragMatrix(event);        } else {          stopDrag();        }        break;      case MotionEvent.ACTION_POINTER_DOWN:        if (mMode == MODE_UNABLE)          return true;        mMode = MODE_ZOOM;        mStartDis = distance(event);        break;      case MotionEvent.ACTION_POINTER_UP:        break;      default:        break;      }      return mGestureDetector.onTouchEvent(event);    }    private void startDrag() {      if (mMoveListener != null)        mMoveListener.startDrag();    }    private void stopDrag() {      if (mMoveListener != null)        mMoveListener.stopDrag();    }    private void checkDragable() {      mLeftDragable = true;      mRightDragable = true;      mFirstMove = true;      float[] values = new float[9];      getImageMatrix().getValues(values);      if (values[Matrix.MTRANS_X] >= 0)        mRightDragable = false;      if ((mImageWidth) * values[Matrix.MSCALE_X]          + values[Matrix.MTRANS_X] <= getWidth()) {        mLeftDragable = false;      }    }    public void setDragMatrix(MotionEvent event) {      if (isZoomChanged()) {        float dx = event.getX() - mStartPoint.x;        float dy = event.getY() - mStartPoint.y;        if (Math.sqrt(dx * dx + dy * dy) > 10f) {          mStartPoint.set(event.getX(), event.getY());          mCurrentMatrix.set(getImageMatrix());          float[] values = new float[9];          mCurrentMatrix.getValues(values);          dy = checkDyBound(values, dy);          dx = checkDxBound(values, dx, dy);          mCurrentMatrix.postTranslate(dx, dy);          setImageMatrix(mCurrentMatrix);        }      } else {        stopDrag();      }    }    private boolean isZoomChanged() {      float[] values = new float[9];      getImageMatrix().getValues(values);      float scale = values[Matrix.MSCALE_X];      return scale != mScale;    }    private float checkDyBound(float[] values, float dy) {      float height = getHeight();      if (mImageHeight * values[Matrix.MSCALE_Y] < height)        return 0;      if (values[Matrix.MTRANS_Y] + dy > 0)        dy = -values[Matrix.MTRANS_Y];      else if (values[Matrix.MTRANS_Y] + dy < -(mImageHeight          * values[Matrix.MSCALE_Y] - height))        dy = -(mImageHeight * values[Matrix.MSCALE_Y] - height)            - values[Matrix.MTRANS_Y];      return dy;    }    private float checkDxBound(float[] values, float dx, float dy) {      float width = getWidth();      if (!mLeftDragable && dx < 0) {        if (Math.abs(dx) * 0.4f > Math.abs(dy) && mFirstMove) {          stopDrag();        }        return 0;      }      if (!mRightDragable && dx > 0) {        if (Math.abs(dx) * 0.4f > Math.abs(dy) && mFirstMove) {          stopDrag();        }        return 0;      }      mLeftDragable = true;      mRightDragable = true;      if (mFirstMove)        mFirstMove = false;      if (mImageWidth * values[Matrix.MSCALE_X] < width) {        return 0;      }      if (values[Matrix.MTRANS_X] + dx > 0) {        dx = -values[Matrix.MTRANS_X];      } else if (values[Matrix.MTRANS_X] + dx < -(mImageWidth          * values[Matrix.MSCALE_X] - width)) {        dx = -(mImageWidth * values[Matrix.MSCALE_X] - width)            - values[Matrix.MTRANS_X];      }      return dx;    }    private void setZoomMatrix(MotionEvent event) {      if (event.getPointerCount() < 2)        return;      float endDis = distance(event);      if (endDis > 10f) {        float scale = endDis / mStartDis;        mStartDis = endDis;        mCurrentMatrix.set(getImageMatrix());        float[] values = new float[9];        mCurrentMatrix.getValues(values);        scale = checkMaxScale(scale, values);        PointF centerF = getCenter(scale, values);        mCurrentMatrix.postScale(scale, scale, centerF.x, centerF.y);        setImageMatrix(mCurrentMatrix);      }    }    private PointF getCenter(float scale, float[] values) {      if (scale * values[Matrix.MSCALE_X] < mScale || scale >= 1) {        return new PointF(getWidth() / 2, getHeight() / 2);      }      float cx = getWidth() / 2;      float cy = getHeight() / 2;      if ((getWidth() / 2 - values[Matrix.MTRANS_X]) * scale < getWidth() / 2)        cx = 0;      if ((mImageWidth * values[Matrix.MSCALE_X] + values[Matrix.MTRANS_X])          * scale < getWidth())        cx = getWidth();      return new PointF(cx, cy);    }    private float checkMaxScale(float scale, float[] values) {      if (scale * values[Matrix.MSCALE_X] > MAX_SCALE)        scale = MAX_SCALE / values[Matrix.MSCALE_X];      return scale;    }    private void reSetMatrix() {      if (checkRest()) {        mCurrentMatrix.set(mMatrix);        setImageMatrix(mCurrentMatrix);      } else {        float[] values = new float[9];        getImageMatrix().getValues(values);        float height = mImageHeight * values[Matrix.MSCALE_Y];        if (height < getHeight()) {          float topMargin = (getHeight() - height) / 2;          if (topMargin != values[Matrix.MTRANS_Y]) {            mCurrentMatrix.set(getImageMatrix());            mCurrentMatrix.postTranslate(0, topMargin                - values[Matrix.MTRANS_Y]);            setImageMatrix(mCurrentMatrix);          }        }      }    }    private boolean checkRest() {      float[] values = new float[9];      getImageMatrix().getValues(values);      float scale = values[Matrix.MSCALE_X];      return scale < mScale;    }    private void isMatrixEnable() {      if (getScaleType() != ScaleType.CENTER) {        setScaleType(ScaleType.MATRIX);      } else {        mMode = MODE_UNABLE;      }    }    private float distance(MotionEvent event) {      float dx = event.getX(1) - event.getX(0);      float dy = event.getY(1) - event.getY(0);      return (float) Math.sqrt(dx * dx + dy * dy);    }    public void onDoubleClick() {      float scale = isZoomChanged() ? 1 : DOUBLE_CLICK_SACLE;      mCurrentMatrix.set(mMatrix);      mCurrentMatrix.postScale(scale, scale, getWidth() / 2,          getHeight() / 2);      setImageMatrix(mCurrentMatrix);    }  }  private class GestureListener extends SimpleOnGestureListener {    private final MatrixTouchListener mTouchListener;    public GestureListener(MatrixTouchListener listener) {      this.mTouchListener = listener;    }    @Override    public boolean onDown(MotionEvent e) {      return true;    }    @Override    public boolean onDoubleTap(MotionEvent e) {      mTouchListener.onDoubleClick();      return true;    }    @Override    public boolean onSingleTapUp(MotionEvent e) {      return super.onSingleTapUp(e);    }    @Override    public void onLongPress(MotionEvent e) {      super.onLongPress(e);    }    @Override    public boolean onScroll(MotionEvent e1, MotionEvent e2,        float distanceX, float distanceY) {      return super.onScroll(e1, e2, distanceX, distanceY);    }    @Override    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,        float velocityY) {      return super.onFling(e1, e2, velocityX, velocityY);    }    @Override    public void onShowPress(MotionEvent e) {      super.onShowPress(e);    }    @Override    public boolean onDoubleTapEvent(MotionEvent e) {      return super.onDoubleTapEvent(e);    }    @Override    public boolean onSingleTapConfirmed(MotionEvent e) {      if (mSingleTapListener != null)        mSingleTapListener.onSingleTap(e);      return super.onSingleTapConfirmed(e);    }  }  public interface OnMovingListener {    public void startDrag();    public void stopDrag();  }  public interface OnSingleTapListener {    public void onSingleTap(MotionEvent e);  }}

我对其中定义OnSingleTapListener接口的方法稍作了一些修改,为onSingleTap回调方法增加了MotionEvent类型的参数,来方便我们根据用户具体的事件内容作出对应的控制。ks4HTML5中文学习网 - HTML5先行者学习网

以上就是本文的全部内容,希望对大家学习Android软件编程有所帮助。ks4HTML5中文学习网 - HTML5先行者学习网

(责任编辑:)
推荐书籍
推荐资讯
关于HTML5先行者 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 人才招聘 - 帮助