本文实例实现的主要功能是在ImageVIEw中识别手势用以控制图片放大或缩小,具有一定的参考价值,分享给大家。
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,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,float veLocityX,float veLocityY) { return super.onFling(e1,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类型的参数,来方便我们根据用户具体的事件内容作出对应的控制。
以上就是本文的全部内容,希望对大家学习AndroID软件编程有所帮助。
总结以上是内存溢出为你收集整理的Android实现手势控制ImageView图片大小全部内容,希望文章能够帮你解决Android实现手势控制ImageView图片大小所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)