android中的划屏事件 GestureDetector.OnGestureListener 详解(二)

  • 按下(onDown): 刚刚手指接触到触摸屏的那一刹那,就是触的那一下。

  • 抛掷(onFling): 手指在触摸屏上迅速移动,并松开的动作。

  • 长按(onLongPress): 手指按在持续一段时间,并且没有松开。

  • 滚动(onScroll): 手指在触摸屏上滑动。

  • 按住(onShowPress): 手指按在触摸屏上,它的时间范围在按下起效,在长按之前。

  • 抬起(onSingleTapUp):手指离开触摸屏的那一刹那。

除了这些定义之外,鄙人也总结了一点算是经验的经验吧,在这里和大家分享一下。

  • 任何手势动作都会先执行一次按下(onDown)动作。

  • 长按(onLongPress)动作前一定会执行一次按住(onShowPress)动作。

  • 按住(onShowPress)动作和按下(onDown)动作之后都会执行一次抬起(onSingleTapUp)动作。

  • 长按(onLongPress)、滚动(onScroll)和抛掷(onFling)动作之后都不会执行抬起(onSingleTapUp)动作。





当用户触摸屏幕的时候,会产生许多手势,例如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提供给我们的一个更方便的响应不同手势的类,这个类实现了上述两个接口(但是所有的方法体都是空的),该类是static class,也就是说它实际上是一个外部类。程序员可以在外部继承这个类,重写里面的手势处理方法。

通过GestureDetector的构造方法可以将SimpleOnGestureListener对象传递进去,这样GestureDetector能处理不同的手势了。


有时候我们并不需要处理上面所有手势,方便起见,Android提供了另外一个类SimpleOnGestureListener实现了如上接口,我们只需要继承SimpleOnGestureListener然后重载感兴趣的手势即可。


对于自定义View,使用手势识别有两处陷阱可能会浪费你的不少时间。

 

1:View必须设置longClickable为true,否则手势识别无法正确工作,只会返回Down, Show, Long三种手势

 

2:必须在View的onTouchListener中调用手势识别,而不能像Activity一样重载onTouchEvent,否则同样手势识别无法正确工作




定义GestureDetector时会提示构造器已经弃用要加上忽视警告语句:@SuppressWarnings("deprecation")  GestureDetector会被划上条横线代表此语句已经过时

修改:

<span style="font-size: 18px;">随着<a target=_blank target="_blank" class="inner-link decor-none" href="http://zhidao.baidu.com/search?word=Android%20SDK&fr=qb_search_exp&ie=utf8" rel="nofollow" style="color: rgb(45, 100, 179); text-decoration: none;">Android SDK</a><img src="https://i-blog.csdnimg.cn/blog_migrate/fd7ce48e38a4bcdc1d7050201367a908.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />升级<img src="https://i-blog.csdnimg.cn/blog_migrate/86df388af00f5709d701a4ba4711f02c.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" /><img src="http://img.iknow.bdimg.com/question/word/yi3.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />前<img src="https://i-blog.csdnimg.cn/blog_migrate/fd7ce48e38a4bcdc1d7050201367a908.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />某些接口<img src="http://img.iknow.bdimg.com/question/word/ke.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />能有更好、更安全<img src="https://i-blog.csdnimg.cn/blog_migrate/fd7ce48e38a4bcdc1d7050201367a908.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />接口来代替<img src="http://img.iknow.bdimg.com/question/word/stop.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />Android开发团队会把过时<img src="https://i-blog.csdnimg.cn/blog_migrate/fd7ce48e38a4bcdc1d7050201367a908.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />接口标识成deprecated, <img src="https://i-blog.csdnimg.cn/blog_migrate/e1844be2a7cae6c5d66b16a310d84c07.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" /><img src="https://i-blog.csdnimg.cn/blog_migrate/5546c3ab6bee1d9be9918e78ae798c34.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" /><img src="http://img.iknow.bdimg.com/question/word/zai.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />开发文档<img src="http://img.iknow.bdimg.com/question/word/zhong.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />提示使用<img src="http://img.iknow.bdimg.com/question/word/zui.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />新<img src="https://i-blog.csdnimg.cn/blog_migrate/fd7ce48e38a4bcdc1d7050201367a908.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />代替接口<img src="http://img.iknow.bdimg.com/question/word/stop.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />
<img src="http://img.iknow.bdimg.com/question/word/ni.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />用<img src="http://img.iknow.bdimg.com/question/word/dao.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" /><img src="https://i-blog.csdnimg.cn/blog_migrate/fd7ce48e38a4bcdc1d7050201367a908.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />GestureDetector<img src="https://i-blog.csdnimg.cn/blog_migrate/fd7ce48e38a4bcdc1d7050201367a908.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" /><a target=_blank target="_blank" class="inner-link decor-none" href="http://zhidao.baidu.com/search?word=%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0&fr=qb_search_exp&ie=utf8" rel="nofollow" style="color: rgb(45, 100, 179); text-decoration: none;">构造函数</a><img src="http://img.iknow.bdimg.com/question/word/zai.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />4.1版本<img src="http://img.iknow.bdimg.com/question/word/zhong.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />已经过时<img src="https://i-blog.csdnimg.cn/blog_migrate/86df388af00f5709d701a4ba4711f02c.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" /><img src="http://img.iknow.bdimg.com/question/word/ke.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" /><img src="http://img.iknow.bdimg.com/question/word/yi3.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />使用推荐<img src="https://i-blog.csdnimg.cn/blog_migrate/fd7ce48e38a4bcdc1d7050201367a908.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />:
mGestureDetector = new GestureDetector(this, this);
// 注意前<img src="https://i-blog.csdnimg.cn/blog_migrate/523d7b72f534642f78277dc572075e9d.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" /><img src="https://i-blog.csdnimg.cn/blog_migrate/9ae775c5ffe95e660ce75bc7318ffbfd.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />this代表<img src="https://i-blog.csdnimg.cn/blog_migrate/fd7ce48e38a4bcdc1d7050201367a908.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" /><img src="http://img.iknow.bdimg.com/question/word/shi.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" /><img src="https://i-blog.csdnimg.cn/blog_migrate/523d7b72f534642f78277dc572075e9d.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" /><img src="https://i-blog.csdnimg.cn/blog_migrate/9ae775c5ffe95e660ce75bc7318ffbfd.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />Context,<img src="https://i-blog.csdnimg.cn/blog_migrate/5546c3ab6bee1d9be9918e78ae798c34.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" /><img src="https://i-blog.csdnimg.cn/blog_migrate/523d7b72f534642f78277dc572075e9d.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" /><img src="https://i-blog.csdnimg.cn/blog_migrate/9ae775c5ffe95e660ce75bc7318ffbfd.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />this代表<img src="https://i-blog.csdnimg.cn/blog_migrate/fd7ce48e38a4bcdc1d7050201367a908.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" /><img src="http://img.iknow.bdimg.com/question/word/shi.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" /><img src="https://i-blog.csdnimg.cn/blog_migrate/523d7b72f534642f78277dc572075e9d.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" /><img src="https://i-blog.csdnimg.cn/blog_migrate/9ae775c5ffe95e660ce75bc7318ffbfd.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />OnGestureListener<img src="http://img.iknow.bdimg.com/question/word/stop.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />
// Activity继承自Context, 而<img src="http://img.iknow.bdimg.com/question/word/ni.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" /><img src="https://i-blog.csdnimg.cn/blog_migrate/fd7ce48e38a4bcdc1d7050201367a908.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" />activity应该实现了(implements)OnGestureListener接口<img src="http://img.iknow.bdimg.com/question/word/stop.png" class="word-replace" alt="" style="border: 0px; max-width: 100%; vertical-align: middle;" /></span>






2.、具体用法:Android Touch Screen 与传统Click Touch Screen不同,会有一些手势(Gesture),例如Fling,Scroll等等。这些Gesture会使用户体验大大提升。Android中的Gesture识别(detector)是通过GestureDetector.OnGestureListener接口实现的。

首先,Android事件处理机制是基于Listener实现的,比如触摸屏相关的事件,就是通过onTouchListener实现;

其次,所有View的子类都可以通过setOnTouchListener()、setOnKeyListener()等方法来添加对某一类事件的Listener;

第三,Listener一般会以Interface的方式来提供,其中包含一个或多个abstract方法,我们需要实现这些方法来完成onTouch()、onKey()等操作。这样,程序便可以在特定的事件被dispatch到该view的时候,通过callback函数给予适当的响应。

1. Touch Screen Click举例

Java代码  复制代码  收藏代码
  1. public class MyGesture extends Activity implements OnTouchListener {   
  2.     public void onCreate(Bundle savedInstanceState) {   
  3.         super.onCreate(savedInstanceState);   
  4.         setContentView(R.layout.main);   
  5.         TextView tv = (TextView) findViewById(R.id.tv);   
  6.         tv.setOnTouchListener(this);   
  7.     }   
  8.     public boolean onTouch(View v, MotionEvent event) {   
  9.         Toast.makeText(this"Touch Touch", Toast.LENGTH_SHORT).show();   
  10.         return false;   
  11.     }   
  12. }  
我们可以通过MotionEvent的getAction()方法来获取Touch事件的类型,包括 ACTION_DOWN(按下触摸屏), ACTION_MOVE(按下触摸屏后移动受力点), ACTION_UP(松开触摸屏)和ACTION_CANCEL(不会由用户直接触发)。借助对于用户不同操作的判断,结合getRawX()、getRawY()、getX()和getY()等方法来获取坐标后,我们可以实现诸如拖动某一个按钮,拖动滚动条等功能。

2. 回到今天的重点,当我们捕捉到Touch操作的时候,如何识别出用户的Gesture?这里我们需要GestureDetector.OnGestureListener接口的帮助,代码如下:

Java代码  复制代码  收藏代码
  1. public class MyGesture extends Activity implements OnTouchListener, OnGestureListener {   
  2.     private GestureDetector mGestureDetector;   
  3.     public MyGesture() {   
  4.         mGestureDetector = new GestureDetector(this);   
  5.     }   
  6.     public void onCreate(Bundle savedInstanceState) {   
  7.         super.onCreate(savedInstanceState);   
  8.         setContentView(R.layout.main);   
  9.         TextView tv = (TextView) findViewById(R.id.tv);   
  10.         tv.setOnTouchListener(this);   
  11.         tv.setFocusable(true);   
  12.         tv.setClickable(true);   
  13.         tv.setLongClickable(true);   
  14.         mGestureDetector.setIsLongpressEnabled(true);   
  15.     }   
  16.        
  17.     /*  
  18.      * 在onTouch()方法中,我们调用GestureDetector的onTouchEvent()方法,将捕捉到的MotionEvent交给GestureDetector  
  19.      * 来分析是否有合适的callback函数来处理用户的手势  
  20.      */    
  21.     public boolean onTouch(View v, MotionEvent event) {   
  22.         return mGestureDetector.onTouchEvent(event);   
  23.     }   
  24.   
  25.     // 用户轻触触摸屏,由1个MotionEvent ACTION_DOWN触发   
  26.     public boolean onDown(MotionEvent arg0) {   
  27.         Log.i("MyGesture""onDown");   
  28.         Toast.makeText(this"onDown", Toast.LENGTH_SHORT).show();   
  29.         return true;   
  30.     }   
  31.        
  32.     /*  
  33.      * 用户轻触触摸屏,尚未松开或拖动,由一个1个MotionEvent ACTION_DOWN触发  
  34.      * 注意和onDown()的区别,强调的是没有松开或者拖动的状态  
  35.      */  
  36.     public void onShowPress(MotionEvent e) {   
  37.         Log.i("MyGesture""onShowPress");   
  38.         Toast.makeText(this"onShowPress", Toast.LENGTH_SHORT).show();   
  39.     }   
  40.        
  41.     // 用户(轻触触摸屏后)松开,由一个1个MotionEvent ACTION_UP触发   
  42.     public boolean onSingleTapUp(MotionEvent e) {   
  43.         Log.i("MyGesture""onSingleTapUp");   
  44.         Toast.makeText(this"onSingleTapUp", Toast.LENGTH_SHORT).show();   
  45.         return true;   
  46.     }   
  47.        
  48.     // 用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE, 1个ACTION_UP触发   
  49.     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {   
  50.         Log.i("MyGesture""onFling");   
  51.         Toast.makeText(this"onFling", Toast.LENGTH_LONG).show();   
  52.         return true;   
  53.     }   
  54.        
  55.     // 用户按下触摸屏,并拖动,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE触发   
  56.     public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {   
  57.         Log.i("MyGesture""onScroll");   
  58.         Toast.makeText(this"onScroll", Toast.LENGTH_LONG).show();   
  59.         return true;   
  60.     }   
  61.        
  62.     // 用户长按触摸屏,由多个MotionEvent ACTION_DOWN触发   
  63.     public void onLongPress(MotionEvent e) {   
  64.         Log.i("MyGesture""onLongPress");   
  65.         Toast.makeText(this"onLongPress", Toast.LENGTH_LONG).show();   
  66.     }   
  67. }  

滑屏实现:

 

通过android.view.GestureDetector类可以检测各种手势事件,该类有两个回调接口分别用来通知具体的事件:
 
GestureDetector.OnDoubleTapListener:用来通知DoubleTap事件,类似于鼠标的双击事件,该接口有如下三个回调函数:
 
1.   onDoubleTap(MotionEvent e):通知DoubleTap手势,
2.   onDoubleTapEvent(MotionEvent e):通知DoubleTap手势中的事件,包含down、up和move事件(这里指的是在双击之间发生的事件,例如在同一个地方双击会产生DoubleTap手势,而在DoubleTap手势里面还会发生down和up事件,这两个事件由该函数通知);
3.   onSingleTapConfirmed(MotionEvent e):用来判定该次点击是SingleTap而不是DoubleTap,如果连续点击两次就是DoubleTap手势,如果只点击一次,系统等待一段时间后没有收到第二次点击则判定该次点击为SingleTap而不是DoubleTap,然后触发SingleTapConfirmed事件。
GestureDetector.OnGestureListener:用来通知普通的手势事件,该接口有如下六个回调函数:
1.   onDown(MotionEvent e):down事件;
2.   onSingleTapUp(MotionEvent e):一次点击up事件;
3.   onShowPress(MotionEvent e):down事件发生而move或则up还没发生前触发该事件;
4.   onLongPress(MotionEvent e):长按事件;
5.   onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY):滑动手势事件;
6.   onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY):在屏幕上拖动事件。
本次仅用到了 OnGestureListener类中的onFling方法。  其他手势事件各位可以自己回去试验。
简单说明:
要实现屏幕切换的话,首先需要定义一个GestureDetector:
private GestureDetector mGestureDetector;
 
并在onCreate函数中初始化:
mGestureDetector =  new GestureDetector( this);
 
同时Activity要继承OnGestureListener接口,并实现其中的onFling方法。
另外Activity的onTouchEvent事件也要实现!!
另外本例View切换时还有动画效果。使用Animation类实现,相关的函数: 
  • setInAnimation:设置View进入屏幕时候使用的动画,该函数有两个版本:
一个接受单个参数,类型为android.view.animation.Animation;
一个接受两个参数,类型为Context和int,分别为Context对象和定义Animation的resourceID。
  • setOutAnimation: 设置View退出屏幕时候使用的动画,参数setInAnimation函数一样。
  • showNext: 调用该函数来显示FrameLayout里面的下一个View。
  • showPrevious: 调用该函数来显示FrameLayout里面的上一个View。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值