android 多点触碰实现图片的缩放

package com.siyehuazhilian.view;

import com.siyehuazhilian.touchcontrol.R;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;

public class TouchImageView extends SurfaceView implements Callback {
	private SurfaceHolder holder = null;
	private Bitmap bitmap = null;
	private Matrix matrix = null;

	// 一根手指在触碰
	private int ONE_TOUCH = 1;
	// 多根手指在触碰
	private int MORE_TOUCH = 2;
	// 当前触碰的手指模拟
	private int currentTouch = 0;

	// 单根手指触碰的开始点
	private Point startPoint;

	// 多根手指滑动的前后距离
	private float dis1;
	private float dis2;
	// 多根手指滑动的中心点
	private Point centerPoint;

	public TouchImageView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	public TouchImageView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public TouchImageView(Context context) {
		super(context);
		init();
	}

	/**
	 * 初始化
	 */
	private void init() {
		holder = this.getHolder();
		holder.addCallback(this);

		// 得到一个Bitmap对象
		bitmap = ((BitmapDrawable) getResources().getDrawable(
				R.drawable.img_027)).getBitmap();

		matrix = new Matrix();

		startPoint = new Point();
		centerPoint = new Point();
	}

	/**
	 * 绘画
	 */
	private void draw() {
		// 锁定画布
		Canvas canvas = holder.lockCanvas();
		if (canvas == null) {
			return;
		}

		// 清除画布
		canvas.drawColor(Color.BLACK);

		// 画图片
		canvas.drawBitmap(bitmap, matrix, null);

		// 解锁画布并提交
		holder.unlockCanvasAndPost(canvas);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {

		// 能接受单根和多根手指的触碰
		switch (event.getAction() & MotionEvent.ACTION_MASK) {
		case MotionEvent.ACTION_DOWN:
			// 得到单根手指一开始接触的坐标
			startPoint.set((int) event.getX(), (int) event.getY());
			// 设置模式为单根手指
			currentTouch = ONE_TOUCH;
			break;
		case MotionEvent.ACTION_POINTER_DOWN:
			// 得到两根手指一开始触碰的距离
			dis1 = getDistance(event);
			// 得到这两根手指的中心点
			getCenter(event);
			// 设置模式为多根手指触碰
			currentTouch = MORE_TOUCH;
			break;
		case MotionEvent.ACTION_MOVE:
			if (currentTouch == ONE_TOUCH) {
				// 如果是一根手指,则设置平移,平移的距离是从开始点到现在的移动点
				matrix.postTranslate((event.getX() - startPoint.x) / 10,
						(event.getY() - startPoint.y) / 10);
			} else if (currentTouch == MORE_TOUCH) {
				// 如果是多根手指模式,则设置缩放,缩放的比例是刚接触时两根手指之间的距离与移动后两根手指之间的距离比.
				// 缩放的中心点是刚接触时两根手指的中心点
				dis2 = getDistance(event);
				matrix.postScale((dis2 / dis1), (dis2 / dis1), centerPoint.x,
						centerPoint.y);
			}
			break;
		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_POINTER_UP:currentTouch = 0;//手指松开必须设置为0,不然会因为有两根手指其中一根离开而报错
			break;
		default:
			break;
		}

		// 重新画图像
		draw();

		return true;
	}

	/**
	 * 得到两根手指之间的距离
	 * 
	 * @param event
	 * @return
	 */
	private float getDistance(MotionEvent event) {
		float a = event.getX(1) - event.getX(0);
		float b = event.getY(1) - event.getY(0);
		return (float) Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));
	}

	/**
	 * 得到两根手指之间的中心点
	 * 
	 * @param event
	 */
	private void getCenter(MotionEvent event) {
		float a = event.getX(1) + event.getX(0);
		float b = event.getY(1) + event.getY(0);
		centerPoint.set((int) a / 2, (int) b / 2);
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {

	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// 让这个View在创建的时候就开始画画
		draw();
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {

	}

}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面是一个简单的示例代码,实现了继承自UVCCameraTextureView类的多点触碰支持放大缩小和旋转的UVCCamera类: ```java public class UVCCamera extends UVCCameraTextureView { private float mPrevX, mPrevY; private float mScaleFactor = 1f; private float mRotationDegree = 0f; public UVCCamera(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: mPrevX = event.getX(0); mPrevY = event.getY(0); break; case MotionEvent.ACTION_MOVE: if (event.getPointerCount() == 1) { float x = event.getX(0); float y = event.getY(0); float dx = x - mPrevX; float dy = y - mPrevY; mRotationDegree += Math.atan2(dy, dx) * 180 / Math.PI; setRotation(mRotationDegree); mPrevX = x; mPrevY = y; } else if (event.getPointerCount() == 2) { float x1 = event.getX(0); float y1 = event.getY(0); float x2 = event.getX(1); float y2 = event.getY(1); float distance = (float) Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); if (distance > 10f) { float scaleFactor = distance / mPrevDistance; mScaleFactor *= scaleFactor; mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 10.0f)); setScaleX(mScaleFactor); setScaleY(mScaleFactor); } float angle = (float) Math.atan2(y2 - y1, x2 - x1) * 180 / (float) Math.PI; setRotation(angle); mPrevDistance = distance; } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: break; } return true; } } ``` 这个类继承自UVCCameraTextureView,重写了onTouchEvent方法,实现多点触碰支持放大缩小和旋转的功能。当手指只有一个触点时,根据手指移动的方向来旋转图像;当手指有两个触点时,根据两个触点之间的距离来缩放图像,并根据两个触点之间的角度来旋转图像。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值