(1)背景
当用户触摸屏幕的时候,会产生许多手势,例如down,up,scroll,filing等等,我们知道View类有个View.OnTouchListener内部接口,通过重写他的onTouch(View v, MotionEvent event)方法,我们可以处理一些touch事件,但是这个方法太过简单,如果需要处理一些复杂的手势,Android SDK给我们提供了GestureDetector(Gesture:手势Detector:识别)类,通过这个类我们可以识别很多的手势,主要是通过他的onTouchEvent(event)方法完成了不同手势的识别。虽然他能识别手势,但是不同的手势要怎么处理,应该是提供给程序员实现的,因此这个类对外提供了两个接口:OnGestureListener,OnDoubleTapListener,还有一个内部类SimpleOnGestureListener,SimpleOnGestureListener类是GestureDetector提供给我们的一个更方便的响应不同手势的类,这个类实现了上述两个接口。
(2)SimpleOnGestureListener
通过GestureDetector的构造方法可以将SimpleOnGestureListener对象传递进去,这样GestureDetector能处理不同的手势了。
下面是个简单的例子,首先重写GestureDetector类:
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
/**
点击一下非常快的(不滑动)Touchup:
onDown->onSingleTapUp->onSingleTapConfirmed
点击一下稍微慢点的(不滑动)Touchup:
onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed
*/
public class MyGestureDetector extends SimpleOnGestureListener {
//双击的第二下Touch down时触发
@Override
public boolean onDoubleTap(MotionEvent e) {
System.out.println("*********onDoubleTap*******");
return super.onDoubleTap(e);
}
//双击的第二下Touch down和up都会触发,可用e.getAction()区分。
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
System.out.println("*********onDoubleTapEvent*******");
return super.onDoubleTapEvent(e);
}
//Touch down时触发
@Override
public boolean onDown(MotionEvent e) {
System.out.println("*********onDown*******");
return super.onDown(e);
}
//Touch了滑动一点距离后,up时触发。
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float x,
float y) {
System.out.println("*********onFling*******" + x + "******" + y);
return super.onFling(e1, e2, x, y);
}
//Touch了不移动一直Touch down时触发
@Override
public void onLongPress(MotionEvent e) {
System.out.println("*********onLongPress*******");
super.onLongPress(e);
}
/**
Touch了滑动时触发。
输出x,y值
向上划动y为正,向左划时x为正 e1为划动时的Event,e2,为划动后的Event
*/
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float x,
float y) {
System.out.println("*********onScroll*******" + x + "*******" + y);
return super.onScroll(e1, e2, x, y);
}
/**
Touch了还没有滑动时触发
onDown只要Touch down一定立刻触发。
而Touchdown后过一会没有滑动先触发onShowPress再是onLongPress。
所以Touchdown后一直不滑动,onDown->onShowPress->onLongPress这个顺序触发。
*/
@Override
public void onShowPress(MotionEvent e) {
System.out.println("*********onShowPress*******");
super.onShowPress(e);
}
//和onSingleTapup不一样,当监听器确定没有第二次按下事件时,才调用此方法,也就是onSingleTapUp不能确定是单击还是双击,而此方法响应可以确定一定是单击
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
System.out.println("*********onSingleTapConfirmed*******");
return super.onSingleTapConfirmed(e);
}
//只要按下就会调用此方法,当双击时,第一次按下时会调用此方法,而第二次不会调用
@Override
public boolean onSingleTapUp(MotionEvent e) {
System.out.println("*********onSingleTapUp*******");
return super.onSingleTapUp(e);
}
}
public class AaActivity extends Activity {
MyGestureDetector myGestureDetector = null;
GestureDetector gestureDetector = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
gestureDetector = new GestureDetector(this, new MyGestureDetector());
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
}
//这两个函数都是在touch down后又没有滑动(onScroll),又没有长按(onLongPress),然后Touchup时触发
boolean onSingleTapConfirmed(MotionEvent e)
boolean onSingleTapUp(MotionEvent e)
//Touch了不移动一直Touch down时触发
void onLongPress(MotionEvent e)
//Touch了滑动时触发
boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
//Touch了滑动一点距离后,up时触发
boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
/*
Touch了还没有滑动时触发
(与onDown,onLongPress比较,onDown只要Touch down一定立刻触发。
而Touchdown后过一会没有滑动先触发onShowPress再是onLongPress。
所以Touchdown后一直不滑动,onDown->onShowPress->onLongPress这个顺序触发。)
*/
void onShowPress(MotionEvent e)
//Touch down时触发
boolean onDown(MotionEvent e)
//双击的第二下Touch down时触发
boolean onDoubleTap(MotionEvent e)
//双击的第二下Touch down和up都会触发,可用e.getAction()区分
boolean onDoubleTapEvent(MotionEvent e)
- 点击屏幕上的某项的执行流程 有两种情况,一种是时间很短,一种时间稍长
时间很短:onDown–>onSingleTapUp–>onSingleTapConfirmed
时间稍长:onDown–>onShowPress–>onSingleTapUp–>onSingleTapConfirmed - 长按事件:onDown–>onShowPress–>onLongPress
- 拖动:手指触动屏幕后,稍微滑动后立即松开
onDown–>onScroll–>onScroll–>………–>onFling
(3)ScaleGestureDetector
ScaleGestureDetector这个类是专门用来检测两个手指在屏幕上做缩放的手势用的,最简单的应用就是用来缩放图片或者缩放网页。
这个类通常与GestureDetector一起存在,用来处理复杂的手势操作。
通常是单手指和双手指操作,所以通常存在一个判断手指个数然后分发事件的处理方法。
//SimpleOnGestureListener implements OnGestureListener, OnDoubleTapListener
class ZoomGesture extends GestureDetector.SimpleOnGestureListener {//单手指操作
@Override //双击
public boolean onDoubleTap(MotionEvent e) {
System.out.println("--onDoubleTap---");
return true;
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
System.out.println("--onDoubleTapEvent---");
return super.onDoubleTapEvent(e);
}
}
//SimpleOnScaleGestureListener implements OnScaleGestureListener
class ScaleGesture extends ScaleGestureDetector.SimpleOnScaleGestureListener {//双手指操作
@Override
public boolean onScale(ScaleGestureDetector detector) {
detector.getCurrentSpan();//两点间的距离跨度
detector.getCurrentSpanX();//两点间的x距离
detector.getCurrentSpanY();//两点间的y距离
detector.getFocusX(); //
detector.getFocusY(); //
detector.getPreviousSpan(); //上次
detector.getPreviousSpanX();//上次
detector.getPreviousSpanY();//上次
detector.getEventTime(); //当前事件的事件
detector.getTimeDelta(); //两次事件间的时间差
detector.getScaleFactor(); //与上次事件相比,得到的比例因子
return true;
}
}
private GestureDetector gestureDetector; //手势探测器
private ScaleGestureDetector scaleGestureDetector;//比率手势探测器
gestureDetector = new GestureDetector(context, new ZoomGesture());
scaleGestureDetector = new ScaleGestureDetector(context, new ScaleGesture());
public boolean onTouchEvent(MotionEvent event) {
//单点
gestureDetector.onTouchEvent(event);
//双点
scaleGestureDetector.onTouchEvent(event);
return true;