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举例

 public class MyGesture extends Activity implements OnTouchListener {   public void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   setContentView(R.layout.main);   TextView tv = (TextView) findViewById(R.id.tv);   tv.setOnTouchListener(this);   }   public boolean onTouch(View v, MotionEvent event) {   Toast.makeText(this, "Touch Touch", Toast.LENGTH_SHORT).show();   return false;   }
} 

我们可以通过MotionEvent的getAction()方法来获取Touch事件的类型,包括 ACTION_DOWN(按下触摸屏), ACTION_MOVE(按下触摸屏后移动受力点), ACTION_UP(松开触摸屏)和ACTION_CANCEL(不会由用户直接触发)。借助对于用户不同操作的判断,结合getRawX()、 getRawY()、getX()和getY()等方法来获取坐标后,我们可以实现诸如拖动某一个按钮,拖动滚动条等功能。

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

    public class MyGesture extends Activity implements OnTouchListener, OnGestureListener {   private GestureDetector mGestureDetector;   public MyGesture() {   mGestureDetector = new GestureDetector(this);   }   public void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   setContentView(R.layout.main);   TextView tv = (TextView) findViewById(R.id.tv);   tv.setOnTouchListener(this);   tv.setFocusable(true);   tv.setClickable(true);   tv.setLongClickable(true);   mGestureDetector.setIsLongpressEnabled(true);   }   /*  * 在onTouch()方法中,我们调用GestureDetector的onTouchEvent()方法,将捕捉到的MotionEvent交给GestureDetector  * 来分析是否有合适的callback函数来处理用户的手势  */    public boolean onTouch(View v, MotionEvent event) {   return mGestureDetector.onTouchEvent(event);   }   // 用户轻触触摸屏,由1个MotionEvent ACTION_DOWN触发   public boolean onDown(MotionEvent arg0) {   Log.i("MyGesture", "onDown");   Toast.makeText(this, "onDown", Toast.LENGTH_SHORT).show();   return true;   }   /*  * 用户轻触触摸屏,尚未松开或拖动,由一个1个MotionEvent ACTION_DOWN触发  * 注意和onDown()的区别,强调的是没有松开或者拖动的状态  */  public void onShowPress(MotionEvent e) {   Log.i("MyGesture", "onShowPress");   Toast.makeText(this, "onShowPress", Toast.LENGTH_SHORT).show();   }   // 用户(轻触触摸屏后)松开,由一个1个MotionEvent ACTION_UP触发   public boolean onSingleTapUp(MotionEvent e) {   Log.i("MyGesture", "onSingleTapUp");   Toast.makeText(this, "onSingleTapUp", Toast.LENGTH_SHORT).show();   return true;   }   // 用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE, 1个ACTION_UP触发   public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {   Log.i("MyGesture", "onFling");   Toast.makeText(this, "onFling", Toast.LENGTH_LONG).show();   return true;   }   // 用户按下触摸屏,并拖动,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE触发   public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {   Log.i("MyGesture", "onScroll");   Toast.makeText(this, "onScroll", Toast.LENGTH_LONG).show();   return true;   }   // 用户长按触摸屏,由多个MotionEvent ACTION_DOWN触发   public void onLongPress(MotionEvent e) {   Log.i("MyGesture", "onLongPress");   Toast.makeText(this, "onLongPress", Toast.LENGTH_LONG).show();   }   }  

3. Fling事件的处理代码:除了第一个触发Fling的ACTION_DOWN和最后一个ACTION_MOVE中包含的坐标等信息外,我们还可以根据用 户在X轴或者Y轴上的移动速度作为条件。比如下面的代码中我们就在用户移动超过100个像素,且X轴上每秒的移动速度大于200像素时才进行处理。

    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {   // 参数解释:   // e1:第1个ACTION_DOWN MotionEvent   // e2:最后一个ACTION_MOVE MotionEvent   // velocityX:X轴上的移动速度,像素/秒   // velocityY:Y轴上的移动速度,像素/秒   // 触发条件 :   // X轴的坐标位移大于FLING_MIN_DISTANCE,且移动速度大于FLING_MIN_VELOCITY个像素/秒
           final int FLING_MIN_DISTANCE = 100, FLING_MIN_VELOCITY = 200;   if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE && Math.abs(velocityX) > FLING_MIN_VELOCITY) {   // Fling left   Log.i("MyGesture", "Fling left");   Toast.makeText(this, "Fling Left", Toast.LENGTH_SHORT).show();   } else if (e2.getX() - e1.getX() > FLING_MIN_DISTANCE && Math.abs(velocityX) > FLING_MIN_VELOCITY) {   // Fling right   Log.i("MyGesture", "Fling right");   Toast.makeText(this, "Fling Right", Toast.LENGTH_SHORT).show();   }   return false;   }  

这个例子中,tv.setLongClickable( true )是必须的,因为 只有这样,view才能够处理不同于Tap(轻触)的hold(即ACTION_MOVE,或者多个ACTION_DOWN),我们同样可以通过layout定义中的android:longClickable来做到这一点。

4. SimpleOnGestureListener

    public class MyGesture extends Activity implements OnTouchListener {   private GestureDetector mGestureDetector;   public MyGesture() {   mGestureDetector = new GestureDetector(new MySimpleGesture());   }   public void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   setContentView(R.layout.main);   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) {   if (event.getAction() == MotionEvent.ACTION_UP) {   Log.i("MyGesture", "MotionEvent.ACTION_UP");   }   return mGestureDetector.onTouchEvent(event);   }   // SimpleOnGestureListener implements GestureDetector.OnDoubleTapListener, GestureDetector.OnGestureListener  private class MySimpleGesture extends SimpleOnGestureListener {   // 双击的第二下Touch down时触发    public boolean onDoubleTap(MotionEvent e) {   Log.i("MyGesture", "onDoubleTap");   return super.onDoubleTap(e);   }   // 双击的第二下Touch down和up都会触发,可用e.getAction()区分   public boolean onDoubleTapEvent(MotionEvent e) {   Log.i("MyGesture", "onDoubleTapEvent");   return super.onDoubleTapEvent(e);   }   // Touch down时触发    public boolean onDown(MotionEvent e) {   Log.i("MyGesture", "onDown");   return super.onDown(e);   }   // Touch了滑动一点距离后,up时触发   public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {   Log.i("MyGesture", "onFling");   return super.onFling(e1, e2, velocityX, velocityY);   }   // Touch了不移动一直Touch down时触发   public void onLongPress(MotionEvent e) {   Log.i("MyGesture", "onLongPress");   super.onLongPress(e);   }   // Touch了滑动时触发   public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {   Log.i("MyGesture", "onScroll");   return super.onScroll(e1, e2, distanceX, distanceY);   }   /*  * Touch了还没有滑动时触发  * (1)onDown只要Touch Down一定立刻触发  * (2)Touch Down后过一会没有滑动先触发onShowPress再触发onLongPress  * So: Touch Down后一直不滑动,onDown -> onShowPress -> onLongPress这个顺序触发。  */  public void onShowPress(MotionEvent e) {   Log.i("MyGesture", "onShowPress");   super.onShowPress(e);   }   /*  * 两个函数都是在Touch Down后又没有滑动(onScroll),又没有长按(onLongPress),然后Touch Up时触发  * 点击一下非常快的(不滑动)Touch Up: onDown->onSingleTapUp->onSingleTapConfirmed  * 点击一下稍微慢点的(不滑动)Touch Up: onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed   */    public boolean onSingleTapConfirmed(MotionEvent e) {   Log.i("MyGesture", "onSingleTapConfirmed");   return super.onSingleTapConfirmed(e);   }   public boolean onSingleTapUp(MotionEvent e) {   Log.i("MyGesture", "onSingleTapUp");   return super.onSingleTapUp(e);   }   }   }  

转载于:https://www.cnblogs.com/xiaoli3007/p/4329472.html

android——GestureDetector.OnGestureListener 手势详解相关推荐

  1. Android多点触控详解

    本文转载自GcsSloop的 安卓自定义View进阶-多点触控详解 的文章 Android 多点触控详解,在前面的几篇文章中我们大致了解了 Android 中的事件处理流程和一些简单的处理方案,本次带 ...

  2. ANDROID L——Material Design详解(视图和阴影)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! Android L: Google已经确认Android L就是Android Lolli ...

  3. View的事件体系之三 android事件分发机制详解(下)

    接着上一篇来分析事件分发机制,在看了各位大牛的关于事件分发机制的分析后茅塞顿开,之前看过好几遍郭霖,弘扬以及玉刚大神关于事件体系的讲解,一直看不懂,比较模糊,最近复习时,看到一篇博文,写的相当精彩,看 ...

  4. Android涂鸦画板原理详解——从初级到高级(二)

    前言 前面写了<Android涂鸦画板原理详解--从初级到高级(一)>,讲了涂鸦原理初级和中级的应用,现在讲解高级应用.如果没有看过前面一篇文章的同学,建议先去看看哈. 准备 高级涂鸦涉及 ...

  5. Android自定义控件进阶13-MotionEvent详解

    Android MotionEvent 详解,之前用了两篇文章 事件分发机制原理 和 事件分发机制详解 来讲解事件分发,而作为事件分发主角之一的 MotionEvent 并没有过多的说明,本文就带大家 ...

  6. android jar 包 意见反馈功能,android重点jar包详解.docx

    android重点jar包详解 深入理解View(一):从setContentView谈起 我们都知道?MVC,在Android中,这个?V?即指View,那我们今天就来探探View的究竟.在onCr ...

  7. Android应用坐标系统全面详解

    Android应用坐标系统全面详解 原文链接:CSDN@工匠若水,http://blog.csdn.net/yanbober/article/details/50419117 1. 背景 去年有很多人 ...

  8. Android NFC开发实战详解

    Android NFC开发实战详解 Android开发实战详解NFC国内第一本AndroidNFC开发书籍带你开启AndroidNFC开发的神秘之旅大综合案例帮助读者快速进入实战角色:WiFi快速连接 ...

  9. Android Gradle 自定义Task详解二:进阶

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/78523958 本文出自[赵彦军的博客] 系列目录 Android Gradle使用 ...

  10. Android Gradle 自定义Task 详解

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/76408024 本文出自[赵彦军的博客] 系列目录 Android Gradle使用 ...

最新文章

  1. 【硬件】运放的那些事儿
  2. 10年布局,这道题都不懂就别想进阿里
  3. Net::SSH::Perl 模块
  4. html设置无效字符,使用innerHTML属性向head中插入字符时报“无法设置 innerHTML 属性。 该操作的目标元件无效”的错误...
  5. Python键鼠自动化函数
  6. 【BZOJ3609】人人尽说江南好,博弈
  7. java5新特性_5分钟了解Java 12 八大新特性
  8. 32位与4G内存限制
  9. 我刷uvaoj的经历(1)
  10. 操作系统进程通信实验
  11. 如何编写一份高质量的测试报告
  12. 笔记本电脑怎么录制视频
  13. 大疆御2电池数据查看教程
  14. LightOJ - 1395 A Dangerous Maze (II) —— 期望
  15. Uboot SPL的Boot模式选择(从MMC切换到SPI启动)
  16. P4913 【深基16.例3】二叉树深度
  17. LINUX——网络管理
  18. 【CF】3B Lorry
  19. asp.net园林绿化服务交易网站
  20. js文件对比工具mergely

热门文章

  1. 根据文件名 kill 进程
  2. 聊聊我的 ACL2020 论文
  3. 【收藏】机器学习与深度学习核心知识点总结
  4. Nothing is impossible!——致敬Uzi
  5. pyspark对Mysql数据库进行读写
  6. 脚本语言、编程语言区别与联系
  7. Meteor的工作原理及优势与不足
  8. More Exceptional C++起步于Exceptional C++驻足之处
  9. ROC曲线和AUC 原理与实现——Python实战
  10. 5.7 拉普拉斯变换的性质