Android手势识别例子_图片缩放平移预览效果Demo
Android 手势实例、例子主要实现了图片的放大和缩小功能、以及双击放大与缩小
首先我们拿到触摸点的数量、然后求出多个触摸点的平均值、设置给我们的mLastX、mLastY
然后在移动的时候、得到dx、dy进行范围检查以后、调用mScaleMatrix.postTranslate进行设置偏移量
当然了、设置完成以后、还需要再次校验一下、不能把图片移动的与屏幕边界出现白边、校验完成后、调用setImageMatrix.
这里:需要注意一下、我们没有复写ACTION_DOWM、是因为、ACTION_DOWN在多点触控的情况下
只要有一个手指按下状态、其他手指按下不会再次触发ACTION_DOWN、但是多个手指以后、触摸点的平均值会发生很大变化
所以我们没有用到ACTION_DOWN、每当触摸点的数量变化、我们就会跟新当前的mLastX,mLastY.
public boolean onTouch(View v, MotionEvent event) { if (mGestureDetector.onTouchEvent(event)) return true; mScaleGestureDetector.onTouchEvent(event); float x = 0, y = 0; // 拿到触摸点的个数 final int pointerCount = event.getPointerCount(); // 得到多个触摸点的x与y均值 for (int i = 0; i < pointerCount; i++) { x += event.getX(i); y += event.getY(i); } x = x / pointerCount; y = y / pointerCount; //每当触摸点发生变化时,重置mLasX , mLastY if (pointerCount != lastPointerCount) { isCanDrag = false; mLastX = x; mLastY = y; } lastPointerCount = pointerCount; RectF rectF = getMatrixRectF(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (rectF.width() > getWidth() || rectF.height() > getHeight()) { getParent().requestDisallowInterceptTouchEvent(true); } break; case MotionEvent.ACTION_MOVE: if (rectF.width() > getWidth() || rectF.height() > getHeight()) { getParent().requestDisallowInterceptTouchEvent(true); } Log.e(TAG, "ACTION_MOVE"); float dx = x - mLastX; float dy = y - mLastY; if (!isCanDrag) { isCanDrag = isCanDrag(dx, dy); } if (isCanDrag) { if (getDrawable() != null) { isCheckLeftAndRight = isCheckTopAndBottom = true; // 如果宽度小于屏幕宽度,则禁止左右移动 if (rectF.width() < getWidth()) { dx = 0; isCheckLeftAndRight = false; } // 如果高度小雨屏幕高度,则禁止上下移动 if (rectF.height() < getHeight()) { dy = 0; isCheckTopAndBottom = false; } mScaleMatrix.postTranslate(dx, dy); checkMatrixBounds(); setImageMatrix(mScaleMatrix); } } mLastX = x; mLastY = y; break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: Log.e(TAG, "ACTION_UP"); lastPointerCount = 0; break; } return true; }
双击放大与缩小、我们使用了GestureDetector、可以捕获双击事件
因为GestureDetector设置监听器的话、方法一大串、而我们只需要onDoubleTap这个回调
所以我们准备使用它的一个内部类SimpleOnGestureListener、对接口的其他方法实现了空实现
那么、我们双击尺寸如何变化?我是这样的、根据当前的缩放值、如果是小于2的、我们双击直接到变为原图的2倍
如果是2,4之间的、我们双击直接为原图的4倍;其他状态也就是4倍、双击后还原到最初的尺寸
我们双击变化、需要一个动画、比如我们上例的演示图、图片很大、全屏显示的时候initScale=0.5左后
如果双击后变为2、也就是瞬间大了四倍、没有一个过渡的效果的话、给用户的感觉会特别差
所以、我们准备使用postDelay执行一个Runnable、Runnable中再次根据的当然的缩放值继续执行
private class AutoScaleRunnable implements Runnable { static final float BIGGER = 1.07f; static final float SMALLER = 0.93f; private float mTargetScale; private float tmpScale; //缩放的中心 private float x; private float y; //传入目标缩放值,根据目标值与当前值,判断应该放大还是缩小 public AutoScaleRunnable(float targetScale, float x, float y) { this.mTargetScale = targetScale; this.x = x; this.y = y; if (getScale() < mTargetScale) { tmpScale = BIGGER; } else { tmpScale = SMALLER; } } @Override public void run() { // 进行缩放 mScaleMatrix.postScale(tmpScale, tmpScale, x, y); checkBorderAndCenterWhenScale(); setImageMatrix(mScaleMatrix); final float currentScale = getScale(); // 如果值在合法范围内,继续缩放 if (((tmpScale > 1f) && (currentScale < mTargetScale)) || ((tmpScale < 1f) && (mTargetScale < currentScale))) { ZoomImageView.this.postDelayed(this, 16); } else // 设置为目标的缩放比例 { final float deltaScale = mTargetScale / currentScale; mScaleMatrix.postScale(deltaScale, deltaScale, x, y); checkBorderAndCenterWhenScale(); setImageMatrix(mScaleMatrix); isAutoScale = false; } } }
代码就贴到这里、源代码下载链接: http://dwtedx.com/download.html?bdkey=s/1ntwVtDf 密码: lpya