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提供给我们的一个更方便的响应不同手势的类,这个类实现了上述两个接口(但是所有的方法体都是空的),该类是static class,也就是说它实际上是一个外部类。程序员可以在外部继承这个类,重写里面的手势处理方法。
通过GestureDetector的构造方法可以将SimpleOnGestureListener对象传递进去,这样GestureDetector能处理不同的手势了。
2. 具体用法:
2.1
 
DefaultGestureListener.java
 
  1. private class DefaultGestureListener extends SimpleOnGestureListener{
  2. @Override
  3. public boolean onSingleTapUp(MotionEvent e) {
  4. return false;
  5. }
  6. @Override
  7. public void onLongPress(MotionEvent e) {
  8. }
  9. /**
  10. * @param e1 The first down motion event that started the scrolling.
  11. @param e2 The move motion event that triggered the current onScroll.
  12. @param distanceX The distance along the X axis(轴) that has been scrolled since the last call to onScroll. This is NOT the distance between e1 and e2.
  13. @param distanceY The distance along the Y axis that has been scrolled since the last call to onScroll. This is NOT the distance between e1 and e2.
  14. 无论是用手拖动view,或者是以抛的动作滚动,都会多次触发 ,这个方法在ACTION_MOVE动作发生时就会触发 参看GestureDetector的onTouchEvent方法源码
  15. * */
  16. @Override
  17. public boolean onScroll(MotionEvent e1, MotionEvent e2,
  18. float distanceX, float distanceY) {
  19. return false;
  20. }
  21. /**
  22. * @param e1 第1个ACTION_DOWN MotionEvent 并且只有一个
  23. * @param e2 最后一个ACTION_MOVE MotionEvent
  24. * @param velocityX X轴上的移动速度,像素/秒
  25. * @param velocityY Y轴上的移动速度,像素/秒
  26. * 这个方法发生在ACTION_UP时才会触发 参看GestureDetector的onTouchEvent方法源码
  27. *
  28. * */
  29. @Override
  30. public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
  31. float velocityY) {
  32. return false;
  33. }
  34. @Override
  35. public void onShowPress(MotionEvent e) {
  36. }
  37. @Override
  38. public boolean onDown(MotionEvent e) {
  39. return false;
  40. }
  41. @Override
  42. public boolean onDoubleTap(MotionEvent e) {
  43. return false;
  44. }
  45. @Override
  46. public boolean onDoubleTapEvent(MotionEvent e) {
  47. return false;
  48. }
  49. /**
  50. * 这个方法不同于onSingleTapUp,他是在GestureDetector确信用户在第一次触摸屏幕后,没有紧跟着第二次触摸屏幕,也就是不是“双击”的时候触发
  51. * */
  52. @Override
  53. public boolean onSingleTapConfirmed(MotionEvent e) {
  54. return false;
  55. }
  56. }

复制代码

2.2   public GestureDetector (Context context, GestureDetector.OnGestureListener listener)     //通过构造方法将手势响应交给手势识别类2.3   在OnTouchListener的onTouch方法中

  1. private OnTouchListener gestureTouchListener = new OnTouchListener() {
  2. @Override
  3. public boolean onTouch(View v, MotionEvent event) {
  4. return gDetector.onTouchEvent(event);
  5. }
  6. };

复制代码

ok,到此为止就结束了.3.案例:Res.java

  1. package com.android;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.util.Log;
  5. import android.view.GestureDetector;
  6. import android.view.MotionEvent;
  7. import android.view.View;
  8. import android.widget.Button;
  9. public class Res extends Activity implements View.OnTouchListener {
  10. Button btn = null;
  11. private GestureDetector mGestureDetector = null;
  12. /** Called when the activity is first created. */
  13. @Override
  14. public void onCreate(Bundle savedInstanceState) {
  15. super.onCreate(savedInstanceState);
  16. setContentView(R.layout.main);
  17. btn = (Button) findViewById(R.id.button);
  18. btn.setOnTouchListener(this);
  19. mGestureDetector = new GestureDetector(this, new LearnGestureListener());
  20. }
  21. public boolean onTouch(View view, MotionEvent event) {
  22. return mGestureDetector.onTouchEvent(event);
  23. }
  24. class LearnGestureListener extends GestureDetector.SimpleOnGestureListener {
  25. @Override
  26. public boolean onSingleTapUp(MotionEvent ev) {
  27. Log.d("DEBUG","onSingleTapUp");
  28. return true;
  29. }
  30. @Override
  31. public void onShowPress(MotionEvent ev) {
  32. Log.d("DEBUG","onShowPress");
  33. }
  34. @Override
  35. public void onLongPress(MotionEvent ev) {
  36. Log.d("DEBUG","onLongPress");
  37. }
  38. @Override
  39. public boolean onScroll(MotionEvent e1, MotionEvent e2,
  40. float distanceX, float distanceY) {
  41. Log.d("DEBUG","onScroll");
  42. return true;
  43. }
  44. @Override
  45. public boolean onDown(MotionEvent ev) {
  46. Log.d("DEBUG","onDownd");
  47. return true;
  48. }
  49. @Override
  50. public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
  51. float velocityY) {
  52. Log.d("DEBUG","onFling");
  53. return true;
  54. }
  55. public boolean onDoubleTap(MotionEvent event){
  56. Log.d("DEBUG","onDoubleTap");
  57. return true;
  58. }
  59. }
  60. }

复制代码

4.遇到的问题:
1. onFling(***)无法触发
通过设置 mListView.setLongClickable(true);即可(我处理的是ListView的手势事件),只有这样,view才能够处理不同于Tap(轻触)的hold(即ACTION_MOVE,或者多个ACTION_DOWN),我们同样可以通过layout定义中的android:longClickable来做到这一点。
2. 用户长按手机屏幕,就会触发长按事件,离开屏幕时,就会触发up事件,但是SimpleOnGestureListener没有对longPress事件的up事件对外提供接口
解决办法:
类似于这样,截获up事件,因为所有的都是有OnTouchListener 先获得,然后传递给SimpleOnGestureListener的,这里有一点必须要注意:
截获到up事件,我们进行了处理后,必须要将这个事件再交给SimpleOnGestureListener处理,虽然我们只截获长按事件的up,但是SimpleOnGestureListener对于长按事件的up也做了一些处理,只是没有对外提供接口。做了什么处理: 

  1. if (mInLongPress) {
  2. mHandler.removeMessages(TAP);
  3. mInLongPress = false;
  4. }

复制代码

如果不交给SimpleOnGestureListener处理,那么单击动作也会触发onLongPress方法。

  1. private OnTouchListener gestureTouchListener = new OnTouchListener() {
  2. @Override
  3. public boolean onTouch(View v, MotionEvent event) {
  4. switch (event.getAction()) {
  5. case MotionEvent.ACTION_DOWN:
  6. return gDetector.onTouchEvent(event);
  7. case MotionEvent.ACTION_UP:
  8. MyGesture.FlagInfo info = mGesture.getFlagInfo();
  9. if(info.isConnected==true){
  10. int firstVisiblePosition = mListView.getFirstVisiblePosition();
  11. View view = mListView.getChildAt(info.position-firstVisiblePosition);
  12. if(view!=null){
  13. view.setBackgroundResource(R.drawable.listitem_background_blue);
  14. info.isConnected = false;
  15. }
  16. }
  17. return gDetector.onTouchEvent(event);
  18. case MotionEvent.ACTION_MOVE:
  19. return gDetector.onTouchEvent(event);
  20. }
  21. return false;
  22. }
  23. };

复制代码

总结:1. 点击屏幕上的某项的执行流程 有两种情况,一种是时间很短,一种时间稍长
时间很短:onDown——–》onSingleTapUp——–》onSingleTapConfirmed
时间稍长:onDown——–》onShowPress——》onSingleTapUp——–》onSingleTapConfirmed
2. 长按事件
onDown——–》onShowPress——》onLongPress
3.抛:手指触动屏幕后,稍微滑动后立即松开
onDown—–》onScroll—-》onScroll—-》onScroll—-》………—–>onFling
4.拖动
onDown——》onScroll—-》onScroll——》onFiling
注意:有的时候会触发onFiling,但是有的时候不会触发,个人理解是人的动作不标准所致。

android GestureDetector 手势基础的更多相关文章

  1. Android 触摸手势基础 官方文档概览

    Android 触摸手势基础 官方文档概览 触摸手势检测基础 手势检测一般包含两个阶段: 1.获取touch事件数据 2.解析这些数据,看它们是否满足你的应用所支持的某种手势. 相关API: Moti ...

  2. Android 触摸手势基础 官方文档概览2

    Android 触摸手势基础 官方文档概览 触摸手势检测基础 手势检测一般包含两个阶段: 1.获取touch事件数据 2.解析这些数据,看它们是否满足你的应用所支持的某种手势. 相关API: Moti ...

  3. android GestureDetector 手势的判断

    import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.Ges ...

  4. flutter系列之:移动端的手势基础GestureDetector

    目录 简介 Pointers和Listener GestureDetector 手势冲突 总结 简介 移动的和PC端有什么不同呢?同样的H5可以运行在APP端,也可以运行在PC端.两者最大的区别就是移 ...

  5. Android GestureDetector方法详解

    为了加强点击.拖动响应事件,Android提供了GestureDetector手势识别类.通过GestureDetector.OnGestureListener来获取当前被触发的操作手势(Single ...

  6. 看完这篇还不会 GestureDetector 手势检测,我跪搓衣板!

    引言 在 android 开发过程中,我们经常需要对一些手势,如:单击.双击.长按.滑动.缩放等,进行监测.这时也就引出了手势监测的概念,所谓的手势监测,说白了就是对于 GestureDetector ...

  7. Android Content Provider基础

    Android Content Provider基础 Content Providers Content providers管理对一个结构化的数据集合的访问.它们封装了数据,并且提供了保护数据安全性的 ...

  8. Android应用开发基础篇(1)-----Button

    Android应用开发基础篇(1)-----Button   一.概述        Button,顾名思义就是按钮的意思,它主要的功能是响应用户按下按钮时的动作. 二.应用      新建一个工程, ...

  9. 2017 Android 面试题 [ 基础与细节 ]

    2017 Android 面试题 [ 基础与细节 ] 感谢@chuyao抛出的这些问题,平时业务代码写多了,很多基础的东西变得含糊不清了,这次裸辞出来找工作确实没有之前顺利,顺便求上海Android开 ...

随机推荐

  1. 算法与设计模式系列1之Python实现常见算法

    preface 常见的算法包括: 递归算法 二分法查找算法 冒泡算法 插入排序 快速排序 二叉树排序 下面就开始挨个挨个的说说原理,然后用Python去实现: 递归算法 一个函数(或者程序)直接或者间 ...

  2. vimium Keyboard Bindings

    Modifier keys are specified as `<c-x>`, `<m-x>`, and `<a-x>` for ctrl+x, meta+x, a ...

  3. IOS 学习笔记之UI

    自定义控件,实现部分 - (id)initWithFrame:(CGRect)frame descriptionText:(NSArray *)inText/*需要输入两个字符串*/ { self = ...

  4. 如何排查APP服务端和客户端是否支持ATS

    服务端排查 取得客户端直接连接的服务端域名及端口,例如mob.com.cn,端口443,即HTTPS默认端口.针对公网可访问的生产环境地址,建议使用的在线监测工具.https://wosign.ssl ...

  5. apache安装错误error: APR not found解决办法

    linux安装时安装种类不同,一些组件包可能不会被安装,导致linux下安装软件的时候缺这个缺那个,今天为大家介绍linux安装apache时报apr找不到的解决办法 方法/步骤   下载依赖包 wg ...

  6. mvn添加本地jar

    mvn install:install-file -DgroupId=com.oracle "-DartifactId=ojdbc6" "-Dversion=11.2.0 ...

  7. JSP简单标签带属性开发

    1.开发带属性的标签,标签处理器类中属性要有相应setter方法,符合javaBean规范 2.tld文件中进行相应属性标签配置 属性配置相关说明如下图 3.简单标签带属性的例子 1).通过设置标签属 ...

  8. DOCKER windows安装

    DOCKER windows安装 1.下载程序包 2. 设置环境变量 3. 启动DOCKERT 4. 分析start.sh 5. 利用SSH工具管理 6. 下载镜像 6.1 下载地址 6.2 用FTP ...

  9. 英文论文中i.e.,e.g.,etc.,viz.的简要小结

    英文论文中i.e.,e.g.,etc.,viz.的简要小结 看了一堆用法,全白扯,自己总结的最好记,最实用 i.e. =即.换句话说.也就是说."'In essence' or 'in ot ...

  10. js中的preventDefault与stopPropagation详解

    本篇文章主要是对js中的preventDefault与stopPropagation进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助 首先讲解一下js中preventDefault和stopP ...