Android手势识别例子_图片缩放平移预览效果Demo
2014-10-08 11:13:05  By: dwtedx

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

若资源对你有帮助、浏览后有很大收获、不妨小额打赏我一下、你的鼓励是维持我不断写博客最大动力

想获取DD博客最新代码、你可以扫描下方的二维码、关注DD博客微信公众号(ddblogs)

或者你也可以关注我的新浪微博、了解DD博客的最新动态:DD博客官方微博(dwtedx的微博)

如对资源有任何疑问或觉得仍然有很大的改善空间、可以对该博文进行评论、希望不吝赐教

为保证及时回复、可以使用博客留言板给我留言: DD博客留言板(dwtedx的留言板)

感谢你的访问、祝你生活愉快、工作顺心、欢迎常来逛逛


快速评论


技术评论

  • 该技术还没有评论、赶快抢沙发吧...
DD记账
top
+