在android中多指触控通过OnTouchListener监听器监听,触控事件在onTouch方法中分析处理。
在单指触控中,我们常用的三个方法ACTION_DOWN、ACTION_UP、ACTION_MOVE,在多指触控中也会用到,不过用法稍有不同。
多指触控中多了ACTION_POINTER_DOWN、ACTION_POINTER_UP两种情况,这几个情况的触发用法在下面源码中标注:
switch (event.getAction() &MotionEvent.ACTION_MASK) {case MotionEvent.ACTION_DOWN: //第一根手指按下时触发
mode = 1;break;case MotionEvent.ACTION_POINTER_DOWN: //第二根或以上的手指按下时触发
mode += 1;break;case MotionEvent.ACTION_UP: //所有手指都离开时触发
mode = 0;break;case MotionEvent.ACTION_POINTER_UP: //当有两根及以上手指触碰屏幕,其一离开时触发
mode -= 1;break;case MotionEvent.ACTION_MOVE: //此事件非常灵敏,只要有手指触碰屏幕,便会一直触发
if (mode >= 2) {
}break;
}
触碰的手指数可用event.getPointerCount()方法获取。
放大缩小:
此功能可通过手指之间的前后距离倍数来确定放大缩小的倍数,不这样稍微麻烦了点,我们可以用ScaleGestureDetector来实现:
scaleGestureDetector = new ScaleGestureDetector(this, newScaleGestureDetector.OnScaleGestureListener() {
@Overridepublic booleanonScale(ScaleGestureDetector detector) {float factor =detector.getScaleFactor();float x =detector.getFocusX();float y =detector.getFocusY();
Show.log("onScale:" + factor + ";" + x + ";" +y);
matrix.postScale(factor, factor, x, y);
iv.setImageMatrix(matrix);return true;
}
@Overridepublic booleanonScaleBegin(ScaleGestureDetector detector) {
Show.log("onScaleBegin");return true;
}
@Overridepublic voidonScaleEnd(ScaleGestureDetector detector) {
Show.log("onScaleEnd");
}
});
iv=(ImageView) findViewById(R.id.img_test);
iv.setOnTouchListener(newOnTouchListener() {
@Overridepublic booleanonTouch(View v, MotionEvent event) {\
scaleGestureDetector.onTouchEvent(event);return true;
}
});
多指滑动:
先获取各点的中点,而后根据中点的位移来进行判断,下面是一个简单样例:
public class MainActivity extendsActivity {privateImageView iv;
Matrix matrix= newMatrix();privatePointF startPoint;privatePointF nowPoint;
@Overrideprotected voidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startPoint= newPointF();
nowPoint= newPointF();
iv=(ImageView) findViewById(R.id.img_test);
iv.setOnTouchListener(newOnTouchListener() {
@Overridepublic booleanonTouch(View v, MotionEvent event) {switch (event.getAction() &MotionEvent.ACTION_MASK) {caseMotionEvent.ACTION_DOWN:caseMotionEvent.ACTION_POINTER_DOWN:
setEventPoint(event,startPoint);break;caseMotionEvent.ACTION_MOVE:
setEventPoint(event,nowPoint);
Show.log("move:"+getDistance(startPoint,nowPoint));
matrix.postTranslate(nowPoint.x-startPoint.x,nowPoint.y-startPoint.y);
startPoint.set(nowPoint.x,nowPoint.y);break;caseMotionEvent.ACTION_UP:
setEventPoint(event,nowPoint);
Show.log("end:"+getDistance(startPoint,nowPoint));break;
}
iv.setImageMatrix(matrix);return true;
}
});
}private voidsetEventPoint(MotionEvent event, PointF startPoint) {float x = 0, y = 0;final int pointerCount =event.getPointerCount();for (int i = 0; i x+=event.getX(i);
y+=event.getY(i);
}
x= x /pointerCount;
y= y /pointerCount;
startPoint.set(x,y);
}private floatgetDistance(PointF point1,PointF point2){float x = point1.x-point2.x;float y = point1.y-point2.y;return (float) Math.sqrt(x * x + y *y);
}
}