天天看點

Android 多點觸摸 關于Android Matrix的文章 http://www.cnblogs.com/qiengo/archive/2012/06/30/2570874.html

Muilti-touch 雙指縮放的實作

首先要實作OnTouchListener接口,然後重寫方法:

public boolean onTouch(View v, MotionEvent event);       

從這個方法中我們就可以擷取實作兩指縮放功能的全部資訊。

View v是觸發事件的源,MotionEvent event即一個觸摸事件。對螢幕的幾乎所有操作都會觸發事件,如點選、放開、滑動等。

不同的事件在MotionEvent中有不同的id,我們可以根據event.getAction() & MotionEvent.ACTION_MASK的結果來判斷是何種事件。其實就是event.getActionMasked().

有如下事件使我們要用到的:

  • MotionEvent.ACTION_DOWN:在第一個點被按下時觸發
  • MotionEvent.ACTION_UP:當螢幕上唯一的點被放開時觸發
  • MotionEvent.ACTION_POINTER_DOWN:當螢幕上已經有一個點被按住,此時再按下其他點時觸發。
  • MotionEvent.ACTION_POINTER_UP:當螢幕上有多個點被按住,松開其中一個點時觸發(即非最後一個點被放開時)。
  • MotionEvent.ACTION_MOVE:當有點在螢幕上移動時觸發。值得注意的是,由于它的靈敏度很高,而我們的手指又不可能完全靜止(即使我們感覺不到移動,但其實我們的手指也在不停地抖動),是以實際的情況是,基本上隻要有點在螢幕上,此事件就會一直不停地被觸發。

舉例子來說:當我們放一個食指到螢幕上時,觸發ACTION_DOWN事件;再放一個中指到螢幕上,觸發ACTION_POINTER_DOWN事件;此時再把食指或中指放開,都會觸發ACTION_POINTER_UP事件;再放開最後一個手指,觸發ACTION_UP事件;而同時在整個過程中,ACTION_MOVE事件會一直不停地被觸發。

event.getX(index)和event.getY(index)可以擷取到指定index點的坐标,是以當螢幕上有兩個點的時候,我們用如下方法來擷取兩點間的距離:

private float spacing(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);  
}        

 代碼如下:

package com.kelly.dragscale;

import android.app.Activity;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.os.Bundle;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

public class MainActivity extends Activity {

	private ImageView imageView;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		imageView = (ImageView) findViewById(R.id.imageview);

		imageView.setOnTouchListener(new TouchListener());

	}

	private class TouchListener implements OnTouchListener {

		private PointF startPointF = new PointF();
		private Matrix matrix = new Matrix();
		private Matrix currentMatrix = new Matrix();
		private int mode = 0;
		private static final int DRAG = 1;//拖拉
		private static final int ZOOM = 2;//縮放
		float startDis = 0;// 開始距離
		float endDis = 0;// 結束距離
		private PointF midF = new PointF();

		public boolean onTouch(View v, MotionEvent event) {
			
			//event.getActionMasked();
			switch (event.getAction() & MotionEvent.ACTION_MASK) {
			case MotionEvent.ACTION_DOWN://
				mode = DRAG;
				currentMatrix.set(imageView.getImageMatrix());// 記錄imageview目前的移動位置
				startPointF.set(event.getX(), event.getY());

				break;
			case MotionEvent.ACTION_MOVE://
				if (mode == DRAG)// 拖拉模式
				{
					float dx = event.getX() - startPointF.x;
					float dy = event.getY() - startPointF.y;
					matrix.set(currentMatrix);// 在上一次移動的基礎上進行移動
					matrix.postTranslate(dx, dy);
				} else if (mode == ZOOM) {// 縮放模式

					endDis = distance(event);
					if (endDis > 10f) {
						float scale = endDis / startDis;
						matrix.set(currentMatrix);
						matrix.postScale(scale, scale, midF.x, midF.y);
					}

				}

				break;
			case MotionEvent.ACTION_UP://

				break;
			case MotionEvent.ACTION_POINTER_DOWN:// 當螢幕上已經有觸電(手指),再有一個手指按下
				mode = ZOOM;
				startDis = distance(event);
				if (startDis > 10f) {
					midF = getMid(event);
					currentMatrix.set(imageView.getImageMatrix());// 記錄imageview目前的縮放倍數
				}

				break;
			case MotionEvent.ACTION_POINTER_UP://

				mode = 0;

				break;

			default:
				break;
			}

			imageView.setImageMatrix(matrix);
			return true;
		}

		/**
		 * 得到兩點之間的距離
		 * 
		 * @param event
		 * @return
		 */
		private float distance(MotionEvent event) {

			float dx = event.getX(1) - event.getX(0);
			float dy = event.getY(1) - event.getY(0);
			return FloatMath.sqrt(dx * dx + dy * dy);
		}

		/**
		 * 擷取中心點
		 * 
		 * @param event
		 * @return
		 */
		private PointF getMid(MotionEvent event) {

			float dx = (event.getX(1) + event.getX(0)) / 2;
			float dy = (event.getY(1) + event.getY(0)) / 2;

			return new PointF(dx, dy);
		}

	}
}
           

關于Android Matrix的文章 http://www.cnblogs.com/qiengo/archive/2012/06/30/2570874.html