效果图:
功能 :
可以随手指进行自由移动图片
首先将图片按照适当的比例显示在自定义控件中(当图片的宽度或者高度大于控件的宽度或者高度的时候,会对图片进行适当的缩放,当图片的宽高小于控件的宽高的时候,可以进行适当比例的放大,当然后也可以设置是否要进行放大图片的操作,当图片的宽高小于控件的宽高的时候,设置图片显示在控件的中间位置)具体操作过程请点击下面第一条链接进行查看
适当比例设置显示图片:点击查看设置图片显示
设置可随手指自由缩放的图片:点击查看可自由缩放的ImageVeiw
设置双击放大或缩小的图片:点击查看可双击放大或缩小的ImageView
/** *记录上一次多点触控的数量 */ private int mLastPointerCount;
/** * 记录用户最后一次进行多点触控时的位置 */ private float mLastX; private float mLastY;
当 当前的触控点的个数发生变化时,记录当前触摸的中心点的位置
//用于存储多点触控的中心点 float x = 0; float y = 0; //获取多点触控的数量 final int pointerCount = event.getPointerCount(); for (int i = 0; i < pointerCount; i++) { x+=event.getX(i); y+=event.getY(i); } //获取中心点的位置 x/=pointerCount; y/=pointerCount; //说明手指数量发生变化,重新记录中心点坐标 if(mLastPointerCount!=pointerCount){ mLastX = x; mLastY = y; } //记录多点触控的数量 mLastPointerCount = pointerCount;
private RectF getMatrixRectF() { Matrix matrix = mMatrix; final RectF rectF = new RectF(); final Drawable drawable = getDrawable(); if (drawable != null) { rectF.set(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); matrix.mapRect(rectF); } return rectF; }
final RectF matrixRectF1 = getMatrixRectF();
switch (event.getAction()) { case MotionEvent.ACTION_DOWN: break; case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: break; default: break; }
处理ACTION_DOWN中的操作,在这里,我们可以进行一步操作,就是判断一个当前的图片,如果当前的图片的宽度或者高度大于控件的宽度与高度,那么我们可以设置
图片随手指的移动处理逻辑主要是在ACTION_MOVE事件中
case MotionEvent.ACTION_MOVE: //计算偏移量 float dx = x - mLastX; float dy = y - mLastY; //判断当前是否在移动 if (!mIsCanDrag){ mIsCanDrag = isMovesAction(dx, dy); } if (mIsCanDrag) { //如果可以进行移动 isCheckLeftAndRight = isCheckTopAndBottom = true; //拿到缩放后的图片的宽高 final RectF matrixRectF = getMatrixRectF(); if (getDrawable()!=null){ // //如果图片宽度小于控件宽度,不可以进行横向移动 // if (matrixRectF.width()<getWidth()){ // isCheckLeftAndRight = false; // dx =0; // } // //如果图片高度小于控件的高度,不可以进行纵向移动 // if (matrixRectF.height()<getHeight()){ // isCheckTopAndBottom = false; // dy =0; // } mMatrix.postTranslate(dx, dy); setImageMatrix(mMatrix); } } //移动过程中时刻记录更新移动的坐标 mLastX = x; mLastY = y; break;
private boolean isMovesAction(float dx, float dy) { return Math.sqrt(dx*dx+dy*dy)>mTouchSlop; }
private int mTouchSlop; mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
最后,我们需要在ACTION_UP事件中更新mLastPointerCount
case MotionEvent.ACTION_CANCEL: mLastPointerCount = 0;
到这里,我们就实现了图片可以随手指进行多指触控实现自由移动了;
在这里,我们可以进行判定,当图片的宽度高度大于当前的宽度与高度的时候,可以自由移动图片,ViewPager不可以左右滑动,当图片的宽高小于控件的宽高的时候,不允许移动图片,可以滑动viewPager
我们可以在ACTION_MOVE: ACTION_DOWN方法中判断并处理相关事件
case MotionEvent.ACTION_DOWN: //当前的图片是放大的状态的时候,屏蔽父控件的鎆触摸事件 if (matrixRectF1.width()>getWidth()+0.01||matrixRectF1.height()>getHeight()+0.01){ getParent().requestDisallowInterceptTouchEvent(true); } } break;
case MotionEvent.ACTION_MOVE: if (matrixRectF1.width()>getWidth()+0.01||matrixRectF1.height()>getHeight()+0.01){ getParent().requestDisallowInterceptTouchEvent(true); }
在这里,可以在ACTION_UP事件触发时候进行处理
case MotionEvent.ACTION_CANCEL: //当我们的图片的宽度与高度小于控件的宽度与高度的时候,最后手指抬起的时候我们将其移动到控件中心 final RectF matrixRectF = getMatrixRectF(); float deltaX=1.0f; float deltaY=1.0f; if (matrixRectF.width() < getWidth()||matrixRectF.height() < getHeight()) { if (matrixRectF.width() < getWidth()) { deltaX = getWidth() / 2 - matrixRectF.right + matrixRectF.width() / 2; } if (matrixRectF.height() < getHeight()) { deltaY = getHeight() / 2 - matrixRectF.bottom + matrixRectF.height() / 2; } mMatrix.postTranslate(deltaX, deltaY); setImageMatrix(mMatrix); } break
效果图:
本篇脑筋急转弯解析: 稀饭, 因为物以稀为贵