上一篇介绍的onTouch提供的事件还是相对较简单,如果需要处理一些复杂的手势,用这个接口就会很麻烦,因为我们要根据用户触摸的轨迹去判断是什么手势。幸好Android SDK给我们提供了GestureDetector类,通过这个类我们可以识别很多的手势,主要是通过他的onTouchEvent(event)方法完成了不同手势的识别。

介绍

GestureDetector这个类对外提供了两个接口和一个外部类:

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

OnGestureListener有下面的几个动作:

  • 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
    e2:最后一个ACTION_MOVE MotionEvent
    velocityX:X轴上的移动速度,像素/秒
    velocityY:Y轴上的移动速度,像素/秒
  • onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY):在屏幕上拖动事件。无论是用手拖动view,或者是以抛的动作滚动,都会多次触发,这个方法在ACTION_MOVE动作发生时就会触发。

OnDoubleTapListener有下面的几个动作:

  • onSingleTapConfirmed(MotionEvent e):单击事件。用来判定该次点击是SingleTap而不是DoubleTap,如果连续点击两次就是DoubleTap手势,如果只点击一次,系统等待一段时间后没有收到第二次点击则判定该次点击为SingleTap而不是DoubleTap,然后触发SingleTapConfirmed事件。
    触发顺序是:OnDown->OnsingleTapUp->OnsingleTapConfirmed
  • onDoubleTap(MotionEvent e):双击事件。
  • onDoubleTapEvent(MotionEvent e):双击间隔中发生的动作。指触发onDoubleTap以后,在双击之间发生的其它动作,包含down、up和move事件。

关于onSingleTapConfirmed和onSingleTapUp的区别:onSingleTapUp,只要手抬起就会执行,而对于onSingleTapConfirmed来说,如果双击的话,则onSingleTapConfirmed不会执行。

使用Gesture

使用GestureDetector.OnGestureListener接口

要使用OnGestureListener接口,大致有几步要走:
1、创建OnGestureListener监听函数:

private class gestureListener implements GestureDetector.OnGestureListener{  }

2、创建GestureDetector实例:
构造函数有下面三个,根据需要选择:

GestureDetector gestureDetector=new GestureDetector(GestureDetector.OnGestureListener listener);
GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.OnGestureListener listener);
GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.SimpleOnGestureListener listener);  

注:GestureDetector现在已经是deprecation状态,现在推荐GestureDetectorCompat

GestureDetectorCompat gestureDetectorCompat=new GestureDetectorCompat(Context context,GestureDetector.OnGestureListener listener);
GestureDetectorCompat gestureDetectorCompat=new GestureDetectorCompat(Context context,GestureDetector.OnGestureListener listener, Handler handler); 

3、onTouch(View v, MotionEvent event)中拦截,在onTouch()方法中,我们调用GestureDetector的onTouchEvent()方法,将捕捉到的MotionEvent交给GestureDetector来分析是否有合适的callback函数来处理用户的手势

public boolean onTouch(View v, MotionEvent event) {  return gestureDetectorCompat.onTouchEvent(event);
}  

4、控件绑定

TextView tv = (TextView)findViewById(R.id.tv);
tv.setOnTouchListener(this); 

实现代码:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:tools="http://schemas.android.com/tools"  android:layout_width="match_parent"  android:layout_height="match_parent">  <TextView  android:id="@+id/tv"  android:layout_width="fill_parent"  android:layout_height="fill_parent"  android:layout_margin="50dip"  android:background="#76EE00"  android:text="Gesture Detector" />
</RelativeLayout> 
public class MainActivity extends Activity implements OnTouchListener{        private GestureDetectorCompat mGestureDetectorCompat;     @Override  protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);            mGestureDetectorCompat = new GestureDetectorCompat(this, new gestureListener());           TextView tv = (TextView)findViewById(R.id.tv);  tv.setOnTouchListener(this);  tv.setFocusable(true);     tv.setClickable(true);     tv.setLongClickable(true);   }  public boolean onTouch(View v, MotionEvent event) {  return mGestureDetectorCompat.onTouchEvent(event);     }  private class gestureListener implements GestureDetector.OnGestureListener{   public boolean onDown(MotionEvent e) {  showlog("onDown");     Toast.makeText(MainActivity.this, "onDown", Toast.LENGTH_SHORT).show();     return false;  }  public void onShowPress(MotionEvent e) {showlog("onShowPress");     Toast.makeText(MainActivity.this, "onShowPress", Toast.LENGTH_SHORT).show();     }  public boolean onSingleTapUp(MotionEvent e) {  showlog("onSingleTapUp");     Toast.makeText(MainActivity.this, "onSingleTapUp", Toast.LENGTH_SHORT).show();     return true;     }  public boolean onScroll(MotionEvent e1, MotionEvent e2,  float distanceX, float distanceY) {  showlog("onScroll:"+(e2.getX()-e1.getX()) +"   "+distanceX);     Toast.makeText(MainActivity.this, "onScroll", Toast.LENGTH_LONG).show();           return true;     }  public void onLongPress(MotionEvent e) {  showlog("onLongPress");     Toast.makeText(MainActivity.this, "onLongPress", Toast.LENGTH_LONG).show();     }  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,  float velocityY) {  showlog("onFling");     Toast.makeText(MainActivity.this, "onFling", Toast.LENGTH_LONG).show();     return true;  }  };  public void showlog(String info) {System.out.print("GestureDetector "+info);}
}  

使用GestureDetector.OnDoubleTapListener接口

实现OnDoubleTapListener接口的前提是先实现OnGestureListener接口,其实除了第1步,2、3、4步和上面完全一样,不再赘述,下面看下第一步:

同时创建OnGestureListener和OnDoubleTapListener监听函数:
方法一:新建一个类同时派生自OnGestureListener和OnDoubleTapListener:

private class gestureListener implements GestureDetector.OnGestureListener,GestureDetector.OnDoubleTapListener{  }

方法二:使用GestureDetector.setOnDoubleTapListener();函数设置监听:

/构建GestureDetector实例
mGestureDetector = new GestureDetector(new gestureListener());
private class gestureListener implements GestureDetector.OnGestureListener{
}  //设置双击监听器
mGestureDetector.setOnDoubleTapListener(new doubleTapListener());
private class doubleTapListener implements GestureDetector.OnDoubleTapListener{
}  

注:大家可以看到无论在方法一还是在方法二中,都需要派生自GestureDetector.OnGestureListener,前面我们说过GestureDetectorCompat 的构造函数,如下:

GestureDetectorCompat gestureDetectorCompat=new GestureDetectorCompat(Context context,GestureDetector.OnGestureListener listener);
GestureDetectorCompat gestureDetectorCompat=new GestureDetectorCompat(Context context,GestureDetector.OnGestureListener listener, Handler handler);  

可以看到,它的两个构造函数参数都必须是OnGestureListener的实例。所以要想使用OnDoubleTapListener的几个函数,就必须先实现OnGestureListener。
实现代码:

public class MainActivity extends Activity implements OnTouchListener{        private GestureDetectorCompat mGestureDetectorCompat;     @Override  protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);            mGestureDetectorCompat = new GestureDetectorCompat(this, new gestureListener());           TextView tv = (TextView)findViewById(R.id.tv);  tv.setOnTouchListener(this);  tv.setFocusable(true);     tv.setClickable(true);     tv.setLongClickable(true);   }  public boolean onTouch(View v, MotionEvent event) {  return mGestureDetectorCompat.onTouchEvent(event);     }  private class gestureListener implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener{   public boolean onDown(MotionEvent e) {  showlog("onDown");     Toast.makeText(MainActivity.this, "onDown", Toast.LENGTH_SHORT).show();     return false;  }  public void onShowPress(MotionEvent e) {showlog("onShowPress");     Toast.makeText(MainActivity.this, "onShowPress", Toast.LENGTH_SHORT).show();     }  public boolean onSingleTapUp(MotionEvent e) {  showlog("onSingleTapUp");     Toast.makeText(MainActivity.this, "onSingleTapUp", Toast.LENGTH_SHORT).show();     return true;     }  public boolean onScroll(MotionEvent e1, MotionEvent e2,  float distanceX, float distanceY) {  showlog("onScroll:"+(e2.getX()-e1.getX()) +"   "+distanceX);     Toast.makeText(MainActivity.this, "onScroll", Toast.LENGTH_LONG).show();           return true;     }  public void onLongPress(MotionEvent e) {  showlog("onLongPress");     Toast.makeText(MainActivity.this, "onLongPress", Toast.LENGTH_LONG).show();     }  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,  float velocityY) {  showlog("onFling");     Toast.makeText(MainActivity.this, "onFling", Toast.LENGTH_LONG).show();     return true;  }public boolean onSingleTapConfirmed(MotionEvent e) {  showlog("onSingleTapConfirmed");  Toast.makeText(MainActivity.this, "onSingleTapConfirmed",Toast.LENGTH_LONG).show();  return true;  }  public boolean onDoubleTap(MotionEvent e) {  showlog("onDoubleTap");  Toast.makeText(MainActivity.this, "onDoubleTap", Toast.LENGTH_LONG).show();  return true;  }public boolean onDoubleTapEvent(MotionEvent e) {  showlog("onDoubleTapEvent");  Toast.makeText(MainActivity.this, "onDoubleTapEvent", Toast.LENGTH_LONG).show();  return true;  }public void showlog(String info) {System.out.print("GestureDetector "+info);}
}  

使用GestureDetector.SimpleOnGestureListener类

使用OnGestureListener和OnDoubleTapListener接口,这样需要重载接口所有的方法,适合监听所有的手势,如果我们只想监听某个手势或某几个手势呢,这时候就可以使用SimpleOnGestureListener类了。
它与前两个不同的是:
1、这是一个类,在它基础上新建类的话,要用extends派生而不是用implements继承!
2、OnGestureListener和OnDoubleTapListener接口里的函数都是强制必须重写的,即使用不到也要重写出来一个空函数但在SimpleOnGestureListener类的实例或派生类中不必如此,可以根据情况,用到哪个函数就重写哪个函数,因为SimpleOnGestureListener类本身已经实现了这两个接口的所有函数,只是里面全是空的而已。

public class MainActivity extends Activity implements OnTouchListener {  private GestureDetector mGestureDetector;     @Override  protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);            mGestureDetector = new GestureDetector(new simpleGestureListener());            TextView tv = (TextView)findViewById(R.id.tv);  tv.setOnTouchListener(this);  tv.setFocusable(true);     tv.setClickable(true);     tv.setLongClickable(true);   }  public boolean onTouch(View v, MotionEvent event) {  return mGestureDetector.onTouchEvent(event);     }  private class simpleGestureListener extends GestureDetector.SimpleOnGestureListener {  /*****OnGestureListener的函数*****/  public boolean onDown(MotionEvent e) {  Log.i("MyGesture", "onDown");  Toast.makeText(MainActivity.this, "onDown", Toast.LENGTH_SHORT).show();  return false;  }  public void onShowPress(MotionEvent e) {  Log.i("MyGesture", "onShowPress");  Toast.makeText(MainActivity.this, "onShowPress", Toast.LENGTH_SHORT).show();  }  public boolean onSingleTapUp(MotionEvent e) {  Log.i("MyGesture", "onSingleTapUp");  Toast.makeText(MainActivity.this, "onSingleTapUp",  Toast.LENGTH_SHORT).show();  return true;  }  /*****OnDoubleTapListener的函数*****/  public boolean onSingleTapConfirmed(MotionEvent e) {  Log.i("MyGesture", "onSingleTapConfirmed");  Toast.makeText(MainActivity.this, "onSingleTapConfirmed",Toast.LENGTH_LONG).show();  return true;  }  public boolean onDoubleTap(MotionEvent e) {  Log.i("MyGesture", "onDoubleTap");  Toast.makeText(MainActivity.this, "onDoubleTap", Toast.LENGTH_LONG).show();  return true;  }  }
}  

Demo下载地址

Android的手势操作(Gesture)相关推荐

  1. Android的手势操作识别

    转自:http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1020/448.html Android的手势操作识别 时间:2012-10-20 ...

  2. android+p手势操作,手势操作哪家强:Android P对比iPhone X

    [环球网综合科技报道]据科技博客The Verge5月8日的博文称,Android P给谷歌的操作系统带来了大量的更新设计,其中最为突出的是新近推出的手势操作界面系统.很多人注意到该界面系统与苹果去年 ...

  3. android 手势旋转,android中手势操作图片的平移、缩放、旋转

    在网上搜到很多都是一样的版本,只有平移和缩放的功能.我在搜到的源代码基础上添加了旋转和边界检查的功能. 代码主要分两部分,一个activity一个view,代码如下: [java] package c ...

  4. 安卓10.0内测版现新版手势操作:很实用

    iOS和Android的手势操作进步越来越大.比如谷歌在Android 9 Pie上引入了原生的手势,当然,以小米.华为等为代表的OEM厂商也设计具有自身特色的解决方案. 比如原生安卓9.0上,传统的 ...

  5. Android 触摸及手势操作GestureDetector

    现在的智能手机不敢说百分百的都是触摸屏,也应该是百分之九九以上为触摸屏了,触摸屏为我们操作无键盘.无鼠标的手机系统带来了很多的便利.当用户触摸屏幕时会产生很多的触摸事件,down.up.move等等. ...

  6. Android 手势拦截的实现(简化水平、垂直手势操作的拦截处理)

    这是手势拦截类的源码.注释,也加的随地时,方便阅读理解.在源码后面,会有使用案例. package com.laka.robotdog.widget;import android.content.Co ...

  7. android touch事件坐标原点,Android onTouch事件与手势操作

    触摸,手势操作已经很好的融入了我们的生活.那么Android开发中触摸事件要如何捕捉?如何处理?如何识别手势?事件的传递机制又是怎么样的?下面我们将通过一个小例子来进行这方面的学习. 先看效果图 如上 ...

  8. Android之GestureDetector-简单手势操作及通过手势缩放图片,我离职后面试收割小米等大厂offer

    Android提供了手势检测,并为其提供了相应的监听器,需要用到的类是GestureDetector,其实例代表了一个手势检测器,创建GestureDetector时需要传入一个GestureDete ...

  9. 索尼xz2android设置向导,索尼为Xperia XZ2 Premium推送Android 9.0 迎来全新手势操作

    我们此前报道过,索尼曾计划于10月26日为Xperia XZ Premium,Xperia XZ1和Xperia XZ1 Compact推送Android 9.0更新,但是新系统出现了一些软件级的错误 ...

最新文章

  1. 合并两个有序链表分析
  2. Win8 官方培训课程
  3. java通过commons-fileupload实现多张图片的上传(jsp页面)
  4. 解决IE8上传文件时javascript取文件的本地路径的问题C:\fakepath\..
  5. virtualBox文件共享
  6. /a.out , nohut ./a.out , nohup ./a.out 的区别
  7. Sqlite3 ---------------用法
  8. 使用色彩追踪和形态学运算得到图像中感兴趣区域
  9. 12、箱形图和小提琴图的绘制
  10. 目前主流的电脑操作系统
  11. Python练习——用循环求100以内7的倍数
  12. python opencv灰度转rgb
  13. 生成一个点开跳出情人节快乐和鲜花的python代码文件
  14. C++数组求和:关于accumulate函数的使用,简化编写代码量的方法
  15. ubuntu机械盘写入cannot be copied because you do not have permissions to create it in the destination.
  16. 超市自动收款机php,自助收银机,超市无人自动收银系统,海信自助POS,自助收款机...
  17. Android应用代码混淆
  18. 索尼sony xperia xc刷安卓7、8,解锁root教程
  19. iOS 视频播放从零开始(二)
  20. QT使用QMovie播放Gif动画

热门文章

  1. java原理之反射机制
  2. KCP协议:从TCP到UDP家族QUIC/KCP/ENET
  3. Django实现用户注册登录,表单提交后跳转网页(学习笔记)
  4. 【广东工业大学】谭子真丨个人作品展示
  5. 手把手教你使用CNN进行交通标志识别(已开源)
  6. 我要学编程,看什么书好?--^_^,这里推荐一些个人觉得很不错的书(五)小集篇
  7. android 带头像的弹幕,原生Canvas实现带头像的弹幕
  8. 小白的渗透之旅1-DVWA环境搭建
  9. 地下管线探测重点与难点分析
  10. 关于地下管线探测技术发展的思考