安卓 单指移动,双指缩放,双击放大缩小的 iamgeview

本博客基于<a target=_blank href="http://blog.csdn.net/cf125313/article/details/47977059"> 安卓 单指移动,双指缩放的 iamgeview</a>进行的扩展
代码如下


package com.wellav.dolphin.media.ui;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.FloatMath;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.widget.ImageView;

public class ZoomImageView extends ImageView {
	private Matrix matrix = new Matrix();
	private Matrix savedMatrix = new Matrix();

	private static final int NONE = 0;
	private static final int DRAG = 1;
	private static final int ZOOM = 2;
	private int mode = NONE;
	private static final float MAX_SCALE = 3;
	private static float mCurScale = 1.0f;
	private static float mStartScale;
	// 第一个按下的手指的点
	private PointF startPoint = new PointF();
	// 两个按下的手指的触摸点的中点
	private PointF midPoint = new PointF();
	// 初始的两个手指按下的触摸点的距离
	private float oriDis = 1f;

	public ZoomImageView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// mGestureDetector=new GestureDetector(context, new GestureListener());

	}

	private int count = 0;

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		if (count == 0) {
			float[] values = new float[9];
			getImageMatrix().getValues(values);

			mStartScale = values[Matrix.MSCALE_X];
			Log.e("", "s=" + mStartScale);
			count++;
		}

	}

	private float isZoomChanged() {
		float[] values = new float[9];
		getImageMatrix().getValues(values);

		float scale = values[Matrix.MSCALE_X];
		if (scale != mStartScale)
			return mStartScale / scale;
		else
			return 2.0f;
		// return scale!=1.0f;
	}

	@Override
	public void setImageBitmap(Bitmap bm) {
		// TODO Auto-generated method stub
		super.setImageBitmap(bm);

	}

	private long startTime = 0;

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// 进行与操作是为了判断多点触摸
		switch (event.getAction() & MotionEvent.ACTION_MASK) {
		case MotionEvent.ACTION_DOWN:
			// 第一个手指按下事件
			setScaleType(ScaleType.MATRIX);
			long interval = event.getEventTime() - startTime;
			Log.e("", "now-st=" + interval + "st=" + startTime);

			if (interval < 300) {
				Log.e("", "double click");
				matrix.set(getImageMatrix());

				float scale = isZoomChanged();
				Log.e("", "scale=" + scale);
				matrix.postScale(scale, scale, getWidth() / 2, getHeight() / 2);
				setImageMatrix(matrix);
				break;
			}

			startTime = event.getEventTime();
			Log.e("", "down");
			Log.e("", "width=" + getDrawable().getBounds().width());
			matrix.set(getImageMatrix());
			savedMatrix.set(matrix);
			startPoint.set(event.getX(), event.getY());
			mode = DRAG;
			break;
		case MotionEvent.ACTION_POINTER_DOWN:
			// 第二个手指按下事件
			
			Log.e("", "double down");
			oriDis = distance(event);
			if (oriDis > 10f) {
				savedMatrix.set(matrix);
				midPoint = middle(event);
				mode = ZOOM;
			}
			break;
		case MotionEvent.ACTION_UP:
			// 手指放开事件
			mode = NONE;
			break;
		case MotionEvent.ACTION_POINTER_UP:
			// 手指放开事件
			mode = NONE;
			break;
		case MotionEvent.ACTION_MOVE:

			// 手指滑动事件
			if (mode == DRAG) {
				// 是一个手指拖动
				
				matrix.set(savedMatrix);
				Log.e("mmm", "event.getX() - startPoint.x=" + event.getX()
						+ "-" + startPoint.x);
				Log.e("mmm", matrix.toString());
				matrix.postTranslate(event.getX() - startPoint.x, event.getY()
						- startPoint.y);
				Log.e("mmm", "x=" + getX() + "y=" + getY());
			} else if (mode == ZOOM) {
				// 两个手指滑动
				float newDist = distance(event);
				if (newDist > 10f) {
					matrix.set(savedMatrix);
					float scale = newDist / oriDis;
					float[] values = new float[9];
					matrix.getValues(values);
					scale = checkMaxScale(scale, values);
				}
			}
			break;
		}

		// 设置ImageView的Matrix
		this.setImageMatrix(matrix);
		return true;
	}

	/**
	 * 检验scale,使图像缩放后不会超出最大倍数
	 * 
	 * @param scale
	 * @param values
	 * @return
	 */
	private float checkMaxScale(float scale, float[] values) {
		if (scale * values[Matrix.MSCALE_X] > MAX_SCALE)
			scale = MAX_SCALE / values[Matrix.MSCALE_X];
		else if (scale * values[Matrix.MSCALE_X] < mStartScale)
			scale = mStartScale / values[Matrix.MSCALE_X];
		matrix.postScale(scale, scale, getWidth() / 2, getHeight() / 2);
		return scale;
	}

	// 计算两个触摸点之间的距离
	private float distance(MotionEvent event) {
		float x = event.getX(0) - event.getX(1);
		float y = event.getY(0) - event.getY(1);
		return FloatMath.sqrt(x * x + y * y);
	}

	// 计算两个触摸点的中点
	private PointF middle(MotionEvent event) {
		float x = event.getX(0) + event.getX(1);
		float y = event.getY(0) + event.getY(1);
		return new PointF(x / 2, y / 2);
	}

}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无v邪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值