Android图片双指缩放,单指移动实现
16lz
2021-01-23
Android 实现,图片双指缩放,单指移动。通过自定义ImageView控件实现。
ZoomDragImageView.java代码如下:
public class SwZoomDragImageView extends ImageView implements View.OnTouchListener{ private static final String TAG = SwZoomDragImageView.class.getSimpleName(); private boolean support_touch = true;//支持触摸事件 private int mode = 0;// 初始状态 private static final int MODE_DRAG = 1;//平移 private static final int MODE_ZOOM = 2;//缩放 private static final float MAX_SCALE = 4f, MIN_SCALE = 1f;//最大放大倍数,最小放大倍数 float total_scale = MIN_SCALE , current_scale;//total_scale缩放范围2-1,当小于1回弹到1;当大于2回弹到2 private Matrix matrixNow = new Matrix(); private Matrix matrixBefore = new Matrix(); private Matrix mInitializationMatrix = new Matrix();//初始缩放值 private PointF actionDownPoint = new PointF();//点击点 private PointF dragPoint = new PointF();//平移点 private PointF startPoint = new PointF();//滑动点 private PointF mInitializationScalePoint = new PointF();//初始缩放点 private PointF mCurrentScalePoint = new PointF(0, 0);//当前缩放点 private float startDis;//滑动开始距离 /** 两个手指的中间点 */ private PointF midPoint = new PointF(0,0); public SwZoomDragImageView(Context context) { this(context, null); } public SwZoomDragImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public SwZoomDragImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initData(); } private void initData() { if (support_touch) { setOnTouchListener(this); } this.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { SwZoomDragImageView.this.getViewTreeObserver().removeOnGlobalLayoutListener(this); int[] viewLocation = new int[2]; SwZoomDragImageView.this.getLocationInWindow(viewLocation); int viewX = viewLocation[0]; // x 坐标;有bug,在viewpage中。 int viewY = viewLocation[1]; // y 坐标 mInitializationScalePoint.set( SwZoomDragImageView.this.getWidth() / 2, viewY + SwZoomDragImageView.this.getHeight() / 2);//初始化缩放位置 Log.i("yangxun", "控件 宽:" + mInitializationScalePoint.x + "高:" + mInitializationScalePoint.y); } }); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(Color.BLACK);//清空画布 if (matrixNow != null) { canvas.concat(matrixNow);// canvas.setMatrix(matrixNow);//显示有问题 } super.onDraw(canvas); } @Override public void setImageMatrix(Matrix matrix) { matrixNow.set(matrix); invalidate(); } public void resetImageMatrix() { this.matrixNow.set(mInitializationMatrix); invalidate(); } //最小重置数值 private void resetToMinStatus(){ mCurrentScalePoint.set(0, 0); total_scale = MIN_SCALE; } //最大重置数值 private void resetToMaxStatus(){ total_scale = MAX_SCALE; } public float getInitializationBitmapHeight(){ return getHeight()*total_scale; } public float getInitializationBitmapWidth(){ return getWidth()*total_scale; } @Override public boolean onTouch(View v, MotionEvent event) { if (total_scale != 1) { getParent().requestDisallowInterceptTouchEvent(true);//触摸事件请求拦截 } /** 通过与运算保留最后八位 MotionEvent.ACTION_MASK = 255 */ switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN://单指触摸 mode = MODE_DRAG; matrixBefore.set(getImageMatrix()); matrixNow.set(getImageMatrix()); dragPoint.set(event.getX(), event.getY()); actionDownPoint.set(event.getX(), event.getY()); break; case MotionEvent.ACTION_POINTER_DOWN://双指触摸 getParent().requestDisallowInterceptTouchEvent(true);//触摸事件请求拦截 mode = MODE_ZOOM; startPoint.set(event.getX(), event.getY()); startDis = distance(event); /** 计算两个手指间的中间点 */ if (startDis > 10f) { //记录当前ImageView的缩放倍数 matrixBefore.set(getImageMatrix()); matrixNow.set(getImageMatrix()); } break; case MotionEvent.ACTION_MOVE: if (mode == MODE_DRAG && total_scale > 1) { float dx = event.getX() - dragPoint.x; float dy = event.getY() - dragPoint.y; dragPoint.set(event.getX(), event.getY()); imgTransport(dx, dy); } else if (mode == MODE_ZOOM) {//缩放 float endDis = distance(event); midPoint = mid(event); if (endDis > 10f) { current_scale = endDis / startDis;//缩放倍数 total_scale *= current_scale; matrixNow.postScale(current_scale, current_scale, midPoint.x, midPoint.y); invalidate(); } startDis = endDis; } break; case MotionEvent.ACTION_UP: getParent().requestDisallowInterceptTouchEvent(false);//触摸事件请求取消拦截 mode = 0; if(mode == MODE_DRAG) checkClick(event.getX(),event.getY(), actionDownPoint.x, actionDownPoint.y); break; case MotionEvent.ACTION_POINTER_UP: checkZoomValid(); mode = 0; break; } return true; } /** * 平移图片 * @param x * @param y */ public void imgTransport(float x,float y){ mCurrentScalePoint.set(mCurrentScalePoint.x + x, mCurrentScalePoint.y + y); if (mCurrentScalePoint.x >= ((total_scale - 1) * getWidth()) / 2) { mCurrentScalePoint.x = ((total_scale - 1) * getWidth()) / 2; x = 0; } else { if (mCurrentScalePoint.x <= -((total_scale - 1) * getWidth()) / 2) { mCurrentScalePoint.x = -((total_scale - 1) * getWidth()) / 2; x = 0; } } if (mCurrentScalePoint.y >= ((total_scale - 1) * getHeight()) / 2) { mCurrentScalePoint.y = ((total_scale - 1) * getHeight()) / 2; y = 0; } else { if (mCurrentScalePoint.y <= -((total_scale - 1) * getHeight()) / 2) { mCurrentScalePoint.y = -((total_scale - 1) * getHeight()) / 2; y = 0; } } Log.i(TAG, "mCurrentScalePoint.x:" + mCurrentScalePoint.x + " x:" + x); matrixNow.postTranslate(x, y); invalidate(); } private boolean checkZoomValid() { if(mode == MODE_ZOOM){ if(total_scale>MAX_SCALE){ resetToMaxStatus(); matrixNow.set(mInitializationMatrix); matrixNow.postScale(MAX_SCALE, MAX_SCALE, mInitializationScalePoint.x, mInitializationScalePoint.y); matrixNow.postTranslate(mCurrentScalePoint.x, mCurrentScalePoint.y); invalidate(); return false; }else if(total_scale
好了,现在直接使用该类,就可以直接对图片进行相应操作。
更多相关文章
- Android实现图片随意拖动、缩放
- Android 事件总线OTTO用法快速入门
- Android中Activity触摸事件传递源码学习
- 【Android】自定义ImageView高度自适应,宽度成比例缩放
- Android 监听按钮点击事件的三种方式(1:匿名内部类;2:外部类;3:接口方
- android图片缩放(指定大小) drawable获取图片后怎么设置图片大小
- Android 对一个View进行缩放处理(放大或缩小View)案例
- Android 拦截TextView中超链接点击事件
- android 控件onClick事件的4种实现方式