现在一般的Android手机都会使用电容触摸屏最少可以支持两点触摸,多的可能是七八个,所以基本上都会支持多点触控, android系统中应用程序可以使用多点触控的事件来完成各种手势和场景需求。 Android SDK中的MotionEvent类不仅封装了单点触摸的消息,也封装了多点触摸的消息,对于单点触摸和多点触摸的处理方式几乎是一样的。
需要注意的是:Android的多点触控功能需要运行在Android 2.0版本以上。
下面讲一个样例:Activity加载入一个图片,可以通过一个手指对图片进行拖动,也可以通过两个手指的滑动实现图片的放大缩小:
1.主要使用 API 详解:
event.getPointerCount():触控点的个数
getPointerId(int pointerIndex):pointerIndex从0到getPointerCount-1,返回一个触摸点的标示
getX(int pointerIndex):通过标示来得到X坐标
getY(int pointerIndex):通过标示来得到Y坐标
MotionEvent.ACTION_POINTER_1_DOWN:第一个触摸点点击事件
MotionEvent.ACTION_POINTER_2_DOWN:第二个触摸点点击事件
MotionEvent.ACTION_POINTER_1_UP:第一个触摸点松开事件
MotionEvent.ACTION_POINTER_2_UP:第二个触摸点松开事件
2.我们使用 OnTouchListener 监听View,实现一个OnTouchListener的方法,来设置View的侦听属性,然后实现onTouch(View view, MotionEvent event)的方法,就可以获取触屏的感应事件了。
在该事件中,有两个参数可以用来获取对触摸的控制,这两个参数分别为:MotionEvent.getAction()和MotionEvent.ACTION_MASK,前者用于对单点触控进行操作,后者用于对多点触控进行操作,对于单点触控,由MotionEvent.getAction()可以得到以下几种事件:ACTION_DOWN、ACTION_UP,而对于多点触控,由MotionEvent.ACTION_MASK,我们可以得到:ACTION_POINTER_DOWN、ACTION_POINTER_UP,都是MotionEvent中的常量,可以直接调用。而有些常量则是单点和多点共用的,如:ACTION_MOVE,因此在按下时,必须标记单点与多点触控的区别。
3.具体代码实现:
public class MainActivity extends Activity implements View.OnTouchListener{
private ImageView mImageView;
private PointF startPoint = new PointF();
private PointF midPoint ;
private Matrix currentMatrix = new Matrix();
private Matrix matrix = new Matrix();
private float startDis;
private int mode = 0;//0 drag 1 scale
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = (ImageView)findViewById(R.id.imageView);
mImageView.setOnTouchListener(this);
} @Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction() & event.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN: // 第一个手指按下事件
mode =0;
startPoint.set(event.getX(),event.getY());
currentMatrix.set(mImageView.getImageMatrix());
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP: // 手指放开事件
mode = 0;
break; case MotionEvent.ACTION_MOVE:
float x = event.getX() - startPoint.x;
float y = event.getY() - startPoint.y;
if(mode == 0)// 是一个手指拖动
{
matrix.set(currentMatrix);
matrix.postTranslate(x,y);
}else if (mode ==1) // 两个手指滑动 {
float endDistance = distance(event);
if(endDistance>5f)
{
float scale = endDistance/startDis;
matrix.set(currentMatrix);
matrix.postScale(scale,scale,midPoint.x,midPoint.y);
}
} break;
case MotionEvent.ACTION_POINTER_DOWN: // 第二个手指按下事件
mode = 1;
startDis = distance(event);
if(startDis>5f)
{
midPoint = midPoint(event);
currentMatrix.set(mImageView.getImageMatrix());
}
break; }
// 设置ImageView的Matrix
mImageView.setImageMatrix(matrix);
return true;
}
// 计算两个触摸点之间的距离
private float distance(MotionEvent event)
{
float dx = event.getX(1) - event.getX(0);
float dy = event.getY(1) - event.getY(0); return (float)Math.sqrt(dx*dx +dy*dy);
}
// 计算两个触摸点的中点
private PointF midPoint(MotionEvent event)
{
float midX = (event.getX(1)+event.getX(0) )/2;
float midY = (event.getY(1)+event.getY(0) )/2; return new PointF(midX,midY);
}
}
在这段代码中,我们通过手指的操作来计算Matrix的值,然后设置图片的Matrix,实现图片的移动和缩放。
需要注意的是,在资源文件中,需要设置ImageView的scaleType为“matrix”。
Demo 下载