Android 实现根据手势进行缩放的View

1.创建接受并处理View中onTouchEvent的类MultiTouchImpl,在其构造方法中需要传入监听接口,在MultiTouchImpl类中创建一个public方法onTouchEvent来接收View中传递过来的触摸事件

   写onTouchEvent方法:

ACTION为ACTION_POINTER_DOWN时(表示第二次按下):1.记录按下的两个点 2.计算缩放锚点 3.计算两点之间距离 4.抛出监听的抽象方法

ACTION为ACTION_POINTER_UP时(表示第一次抬起):1.记录抬起时的点2.判断是否发生最终缩放3.若发生缩放,则抛出监听的抽象方法,否则return false

ACTION为ACTION_MOVE时:1.记录move的点2.计算两点之间距离,并与距离的初始值进行比较,计算出缩放比例,3.抛出监听的抽象方法

import android.graphics.PointF;
import android.graphics.RectF;
import android.view.MotionEvent;

// MultiTouchImpl.java 
// 实现多点触摸缩放功能

public class MultiTouchImpl {
	enum MULTI_TOUCH_MODE {
		DRAG_ON, DRAG_OFF
	}

	public final static int MAX_TOUCH_POINTS = 2;
	MULTI_TOUCH_MODE mode = MULTI_TOUCH_MODE.DRAG_OFF;
	private PointF mTouchDownPoint0; // 按下触摸屏的位置
	private PointF mTouchDownPoint1; // 按下触摸屏的位置

	PointF pt0;
	PointF pt1;

	float oldDist = 1f;
	private IMultiTouch listener = null;

	private float mStartDistance;

	private PointF mBeginPt;

	public MultiTouchImpl(IMultiTouch context) {
		listener = context;
		mBeginPt = new PointF();
		mTouchDownPoint0 = new PointF();
		mTouchDownPoint1 = new PointF();
		pt0 = new PointF();
		pt1 = new PointF();
	}

	public boolean onTouchEvent(MotionEvent event) {
		int touchPoints = event.getPointerCount();
		if (touchPoints != 2) {
			return true;
		}
		switch (event.getAction() & MotionEvent.ACTION_MASK) {
		case MotionEvent.ACTION_POINTER_DOWN:
			mode = MULTI_TOUCH_MODE.DRAG_ON;
			mBeginPt.set((event.getX(1) + event.getX(0)) / 2,
					(event.getY(1) + event.getY(0)) / 2);
			mStartDistance = getDistance(event.getX(0), event.getY(0),
					event.getX(1), event.getY(1));
			mTouchDownPoint0.set(event.getX(0), event.getY(0));
			mTouchDownPoint1.set(event.getX(1), event.getY(1));
			listener.OnDragBegin();
			break;
		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_POINTER_UP:
			mode = MULTI_TOUCH_MODE.DRAG_OFF;
			pt0.set(event.getX(0), event.getY(0));
			pt1.set(event.getX(1), event.getY(1));
			if (!this.isPointMove(pt0, mTouchDownPoint0)
					&& !this.isPointMove(pt1, mTouchDownPoint1)) {
				// 发送右键
				return false;
			} else {
				listener.OnDragEnd();
			}

			break;
		case MotionEvent.ACTION_MOVE:
			if (mode == MULTI_TOUCH_MODE.DRAG_ON) {
				pt0.set(event.getX(0), event.getY(0));
				pt1.set(event.getX(1), event.getY(1));
				if (this.isPointMove(pt0, mTouchDownPoint0)
						|| this.isPointMove(pt1, mTouchDownPoint1)) {
					float distance = getDistance(event.getX(0), event.getY(0),
							event.getX(1), event.getY(1));

					float scale = 1;
					if (mStartDistance != 0)
						scale = distance / mStartDistance;

					PointF cur = new PointF(
							(event.getX(1) + event.getX(0)) / 2,
							(event.getY(1) + event.getY(0)) / 2);
					listener.OnDraging(mBeginPt, cur, scale);
				}
			}
			break;
		}

		return true;
	}

	public IMultiTouch setListener(IMultiTouch l) {
		IMultiTouch ret = listener;
		listener = l;
		return ret;
	}

	private float getDistance(float x1, float y1, float x2, float y2) {
		float dx = (x2 - x1);
		float dy = (y2 - y1);
		return (float) Math.sqrt((dx * dx + dy * dy));
	}

	private boolean isPointMove(PointF pt, PointF touchPoint) {
		float w = 60.0f;
		RectF rc = new RectF();
		rc.set(touchPoint.x - w / 2, touchPoint.y - w / 2,
				touchPoint.x + w / 2, touchPoint.y + w / 2);
		return !rc.contains(pt.x, pt.y);
	}
}


2.创建监听接口:

接口中定义三个抽象方法OnDragBegin(),OnDraging(PointF begin, PointF end, float mScale),OnDragEnd()

import android.graphics.PointF;

import android.graphics.PointF;

/**
 * @author Q
 * 
 */
public interface IMultiTouch {

	/**
	 * 当缩放手势开始时回调
	 */
	public abstract void OnDragBegin();

	/**
	 * 当缩放手势正在发生时回调, after OnDragBegin(), before OnDragEnd.
	 * 
	 * @param begin
	 *            缩放手势发生时两手批中心点坐标.
	 * @param end
	 *            当前事件(Move)发生时两手指中心点的坐标.
	 * @param mScale
	 *            当前事件发生时两手指距离/手势开始时两手指的距离.
	 */
	public abstract void OnDraging(PointF begin, PointF end, float mScale);

	/**
	 * 当缩放手势结束时回调
	 */
	public abstract void OnDragEnd();
}

3.在自定义View中创建MultiTouchImpl对象,并实现监听接口,在其中的onTouchEvent中,使用MultiTouchImpl的onTouchEvent方法来处理触摸事件。

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		boolean bRetCode = true;
		bRetCode = mMultiTouchImpl.onTouchEvent(event);

		return bRetCode;
	}



你可能感兴趣的:(android开发)