Android之触摸手势检测GestureDetector使用详解

在Android中,当用户触摸屏幕的时候,会产生许多手势,例如down,up,scroll,filing,onSingleTapConfirmed(单击),onDoubleTap(双击)等等。

一般情况下,我们知道View类有个View.OnTouchListener内部接口,通过重写他的onTouch(View v, MotionEvent event)方法,我们可以处理一些在该控件中触发的touch事件,但是这个方法太过简单,如果需要处理一些复杂的手势,用这个接口就会很麻烦(因为我们要自己根据用户触摸的轨迹去判断是什么手势),所以我们常常需要在这个方法中用手势识别器中的onTouchEvent(event)方法去拦截到触摸事件至手势识别器中处理


一、Android sdk给我们提供了GestureDetector(Gesture:手势Detector:识别)类,通过这个类我们可以识别很多的手势,主要是通过他自身的onTouchEvent(event)方法完成了不同手势的识别。他虽然能识别各种手势,但是不同的手势要怎么处理,就需要根据我们自己的需要去实现它内部的三个接口:

接口:OnGestureListener手势识别接口,OnDoubleTapListener双击与单击识别接口 
内部类:SimpleOnGestureListener  这个内部类是静态内部类,实现了OnGestureListener, OnDoubleTapListener接口,相当于是这两个接口功能的集合 

从GestureDetector手势识别类源码中我们也可以清楚的看到这个类中的各个构造方法和接口:


从源码中可以看出,GestureDetector的构造函数中只能传入OnGestureListener接口对象,也就是说,要使用OnDoubleTapListener接口,可以通过setOnDoubleTapListener()设置监听器来实现,但是必须先构造出GestureDetector对象,要构造GestureDetector对象就必须实现OnGestureListener接口。或者使用SimpleOnGestureListener这个内部类,然后自己重写对应的方法。所以不管什么方法要用OnDoubleTapListener接口,就必须先实现OnGestureListener接口。


这个内部类,其实是两个接口中所有函数的集成,它包含了这两个接口里所有必须要实现的函数而且都已经重写,但所有方法体都是空的;不同点在于:该类是static class,我们如果需要用这个内部类,就可以在外面继承这个类,重写里面的手势处理方法。

下面我们先看OnGestureListener接口;

二、GestureDetector.OnGestureListener---接口

1、基本讲解

如果我们要实现OnGestureListener接口,会提示有几个必须重写的函数,加上之后是这个样子的:

detector = new GestureDetector(this, new OnGestureListener() {
	
	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		// TODO Auto-generated method stub
		return false;
	}
	
	@Override
	public void onShowPress(MotionEvent e) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY) {
		// TODO Auto-generated method stub
		return false;
	}
	
	@Override
	public void onLongPress(MotionEvent e) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
			float velocityY) {
		// TODO Auto-generated method stub
		return false;
	}
	
	@Override
	public boolean onDown(MotionEvent e) {
		// TODO Auto-generated method stub
		return false;
	}
});

可见,这里总共重写了六个函数,这些函数都在什么情况下才会触发呢,下面讲一下:

OnDown(MotionEvent e):用户按下屏幕就会触发;
onShowPress(MotionEvent e):如果是按下的时间超过瞬间,不是立即弹起,而且在按下的时候没有松开或者是拖动的,那么onShowPress就会执行
onLongPress(MotionEvent e):长按触摸屏,超过一定时长,就会触发这个事件
    触发顺序:
    onDown->onShowPress->onLongPress

onSingleTapUp(MotionEvent e):从名子也可以看出,一次单独的轻击抬起操作,也就是轻击一下屏幕,立刻抬起来,才会有这个触发,当然,如果除了Down以外还有其它操作,那就不再算是Single操作了,所以也就不会触发这个事件
    触发顺序:
    点击一下非常快的(不滑动)Touchup:
    onDown->onSingleTapUp->onSingleTapConfirmed 
    点击一下稍微慢点的(不滑动)Touchup:
    onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed
onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) :滑屏,用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE, 1个ACTION_UP触发   
     参数解释:
    e1:第1个ACTION_DOWN MotionEvent  可以得到第一次按下时的X轴和Y轴的坐标,分别为:e1.getX(),e1.getY();
    e2:最后一个ACTION_MOVE MotionEvent     可以得到最后一次抬起时的X轴和Y轴的坐标,分别为:e2.getX(),e2.getY();
    velocityX:X轴上的移动速度,像素/秒
    velocityY:Y轴上的移动速度,像素/秒   

onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY):在屏幕上拖动事件。无论是用手拖动view,或者是以抛的动作滚动,都会多次触发,这个方法       在ACTION_MOVE动作发生时就会触发
    滑屏:手指触动屏幕后,稍微滑动后立即松开
    onDown-----》onScroll----》onScroll----》onScroll----》………----->onFling
    拖动
    onDown------》onScroll----》onScroll------》onFiling

    可见,无论是滑屏,还是拖动,影响的只是中间OnScroll触发的数量多少而已,最终都会触发onFling事件!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值