本人新手,最近下了Android L的源码,正在研究手势识别,能力有限,现总结如下:

Android识别触摸屏手势使得用户体验大大提高。在View类中有个View.OnTouchListener内部接口,通过重写他的onTouch(View v, MotionEvent event)方法,我们可以处理一些简单的touch事件,但是这个方法并不能识别手势,如果需要处理一些复杂的手势,用这个接口就会很麻烦(因为我们要自己根据用户触摸的轨迹去判断是什么手势)。好在Android为我们提供了GestureDetector类,通过它,我们可以轻松的进行手势识别。下面我做一个简要地介绍。

一.GestureDetector简介:

1.组成

GestureDetector类用来识别触摸屏的各种手势,它包含了两个接口和两个内部类:

接口:

  OnGestureListener:用来监听手势事件(6种)。

  OnDoubleTapListener:用来监听双击事件。

内部类:

  SimpleOnGestureListener:用来监听所有的手势。实际上它实现了上述两个接口,不过方法体是空的,需要我们自己写。我们可以继承这个类,重写里面的方法进行手势处理。

  GestureHandler:继承了Handler,这是5.0新加的内部类

2.构造(待续)

3.方法(待续)

4.使用

流程:

  首先,系统捕捉屏幕的触摸事件(onTouchListener),这时还未涉及具体手势,只是简单地捕捉到触摸。接着,在onTouch()方法中调用GestureDetector的onTouchEvent()方法,将捕捉到的MotionEvent交给GestureDetector来处理。最后,还需要实现抽象方法。

实现:

  (1)在Activity中创建GestureDetector实例gestureDetector。

  (2)可根据需要选择:

  重写OnGestureListener并通过构造函数传入gestureDetector

  重写OnDoubleTapListener并通过GestureDetector.setOnDoubleTapListener方法传入gestureDetector

  重写SimpleOnGestureListener并通过构造函数传入gestureDetector

  (3)重写Activity的onTouchEvent方法,将所有的触摸事件交给gestureDetector来处理

  public boolean onTouchEvent(MotionEvent event) {
    return gestureDetector.onTouchEvent(event);
  }

 二.接口OnGestureListener

1.onGestureListener识别6种手势,分别是:
  (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):在屏幕上拖动事件。

  关于onFling和onScroll的一点区别。
  onFling()是甩,这个甩的动作是在一个MotionEvent.ACTION_UP(手指抬起)发生时执行,而onScroll(),只要手指移动就会执行。他不会执行MotionEvent.ACTION_UP。onFling通常用来实现翻页效果,而onScroll通常用来实现放大缩小和移动。

2.重写

OnGestureListener onGestureListener=new OnGestureListener(){
  @Override
  public boolean onDown(MotionEvent e) {
  return false;
  }
  @Override
  public boolean onFling(MotionEvent e1, MotionEvent e2,
  float velocityX, float velocityY) {
  return false;
  }
  @Override
  public boolean onLongPress(MotionEvent e) {
  return false;
  }
  @Override
  public boolean onScroll(MotionEvent e1, MotionEvent e2,
  float distanceX, float distanceY) {
  return false;
  }
  @Override
  public void onShowPress(MotionEvent e) {

  }
  @Override
  public boolean onSingleTapUp(MotionEvent e) {
  return false;
  }
  }
3.可以根据需要,在函数里添加具体的处理方法.之后通过构造函数传入GestureDetector即可。
  GestureDetector gestureDetector=new GestureDetector(this,onGestureListener);

三.接口OnDoubleTapListener

1.OnDoubleTapListener是用来检测鼠标双击事件的。需要实现的抽象方法有:

(1) onDoubleTap(MotionEvent e):双击事件。

(2) onDoubleTapEvent(MotionEvent e):双击间隔中还发生其他的动作。通知DoubleTap手势中的事件,包含down、up和move事件

(这里指的是在双击之间发生的事件,例如在同一个地方双击会产生DoubleTap手势,而在DoubleTap手势里面还会发生down和up事件,这两个事件由该函数通知)

(3) onSingleTapConfirmed(MotionEvent e):单击事件。用来判定该次点击是SingleTap而不是DoubleTap,如果连续点击两次就是DoubleTap手势,如果只点击一次,系统等待一段时间后没有收到第二次点击则判定该次点击为SingleTap而不是DoubleTap,然后触发SingleTapConfirmed事件。

  关于onSingleTapConfirmed和onSingleTapUp的一点区别: OnGestureListener有这样的一个方法onSingleTapUp,和onSingleTapConfirmed容易混淆。二者的区别是:onSingleTapUp,只要手抬起就会执行,而对于onSingleTapConfirmed来说,如果双击的话,则onSingleTapConfirmed不会执行。

2.重写

OnDoubleTapListener onDoubleTapListener new OnDoubleTapListener() {
  @Override
  public boolean onSingleTapConfirmed(MotionEvent e) {
  return false;
  }
  @Override
  public boolean onDoubleTapEvent(MotionEvent e) {
  return false;
  }
  @Override
  public boolean onDoubleTap(MotionEvent e) {
  return false;
  }
)

可以根据需要,在函数里添加具体的处理方法.,之后通过setOnDoubleTapListener传入GestureDetector即可。
gestureDetector.setOnDoubleTapListener(onDoubleTapListener) ;

四.内部类SimpleOnGestureListener

SimpleOnGestureListener是GestureDetector类的一个内部类,该类是static class,也就是说它实际上是一个外部类。可以在外部继承这个类,重写里面的手势处理方法。

1.SimpleOnGestureListener实际上实现了OnGestureListener 和OnDoubleTapListener,所以它可以完成以上提到的所有手势识别(9种),如上介绍。

2.重写

public class simpleOnGestureListener extends SimpleOnGestureListener {

  @Override
  public boolean onDoubleTap(MotionEvent e) {
  return super.onDoubleTap(e);
  }
  @Override
  public boolean onDoubleTapEvent(MotionEvent e) {
  return super.onDoubleTapEvent(e);
  }
  @Override
  public boolean onDown(MotionEvent e) {
  return super.onDown(e);
  }
  @Override
  public boolean onFling(MotionEvent e1, MotionEvent e2, float x,
  float y) {
  return super.onFling(e1, e2, x, y);
  }
  @Override
  public void onLongPress(MotionEvent e) {
  super.onLongPress(e);
  }
  @Override
  public boolean onScroll(MotionEvent e1, MotionEvent e2, float x,
  float y) {
  return super.onScroll(e1, e2, x, y);
  }
  @Override
  public void onShowPress(MotionEvent e) {
  super.onShowPress(e);
  }
  @Override
  public boolean onSingleTapConfirmed(MotionEvent e) {
  return super.onSingleTapConfirmed(e);
  }
  @Override
  public boolean onSingleTapUp(MotionEvent e) {
  return super.onSingleTapUp(e);
  }
}

可以根据需要,在函数里添加具体的处理方法,之后通过构造函数传入GestureDetector即可。

GestureDetector gestureDetector=new GestureDetector(this,simpleOnGestureListener );

五.内部类GestureHandler

贴上源代码

     private class GestureHandler extends Handler {
GestureHandler() {
super();
} GestureHandler(Handler handler) {
super(handler.getLooper());
} @Override
public void handleMessage(Message msg) {
switch (msg.what) {
case SHOW_PRESS:
mListener.onShowPress(mCurrentDownEvent);
break; case LONG_PRESS:
dispatchLongPress();
break; case TAP:
// If the user's finger is still down, do not count it as a tap
if (mDoubleTapListener != null) {
if (!mStillDown) {
mDoubleTapListener.onSingleTapConfirmed(mCurrentDownEvent);
} else {
mDeferConfirmSingleTap = true;
}
}
break; default:
throw new RuntimeException("Unknown message " + msg); //never
}
}
}

六.另一种思路(我也没搞清楚)

要实现捕捉屏幕手势,除了在Activity中创建gestureDetector外,还有一种思路:构建一个Overlay,这个Overlay实现OnGestureListener接口,使其维护自己的GestureDetector。
在主视图上添加这个Overlay,并传入相应的listener,即可实现捕捉手势的功能。

Android L(5.0)源码之手势识别GestureDetector的更多相关文章

  1. [Android FrameWork 6.0源码学习] View的重绘过程之WindowManager的addView方法

    博客首页:http://www.cnblogs.com/kezhuang/p/关于Activity的contentView的构建过程,我在我的博客中已经分析过了,不了解的可以去看一下<[Andr ...

  2. [Android FrameWork 6.0源码学习] LayoutInflater 类分析

    LayoutInflater是用来解析XML布局文件,然后生成对象的ViewTree的工具类.是这个工具类的存在,才能让我们写起Layout来那么省劲. 我们接下来进去刨析,看看里边的奥秘 //调用i ...

  3. [Android FrameWork 6.0源码学习] View的重绘过程之Draw

    View绘制的三部曲,测量,布局,绘画现在我们分析绘画部分测量和布局 在前两篇文章中已经分析过了.不了解的可以去我的博客里找一下 下面进入正题,开始分析调用以及函数原理 private void pe ...

  4. [Android FrameWork 6.0源码学习] ViewGroup的addView函数分析

    Android中整个的View的组装是采用组合模式. ViewGroup就相当与树根,各种Layout就相当于枝干,各种子View,就相当于树叶. 至于View类.我们就当它是个种子吧.哈哈! Vie ...

  5. [Android FrameWork 6.0源码学习] View的重绘过程

    View绘制的三部曲,  测量,布局,绘画今天我们分析测量过程 view的测量是从ViewRootImpl发起的,View需要重绘,都是发送请求给ViewRootImpl,然后他组织重绘在重绘的过程中 ...

  6. [Android FrameWork 6.0源码学习] Window窗口类分析

    了解这一章节,需要先了解LayoutInflater这个工具类,我以前分析过:http://www.cnblogs.com/kezhuang/p/6978783.html Window是Activit ...

  7. [Android FrameWork 6.0源码学习] View的重绘过程之Layout

    View绘制的三部曲,测量,布局,绘画现在我们分析布局部分测量部分在上篇文章中已经分析过了.不了解的可以去我的博客里找一下 View的布局和测量一样,都是从ViewRootImpl中发起,ViewRo ...

  8. [Android FrameWork 6.0源码学习] View的重绘ViewRootImpl的setView方法

    博客首页:http://www.cnblogs.com/kezhuang/p/ 本篇文章来分析一下WindowManager的后续工作,也就是ViewRootImpl的setView函数的工作 /i* ...

  9. Android音乐播放器源码(歌词.均衡器.收藏.qq5.0菜单.通知)

    一款Android音乐播放器源码,基本功能都实现了 qq5.0菜单(歌词.均衡器.收藏.qq5.0菜单.通知) 只有向右滑动出现,菜单键和指定按钮都还没有添加. 源码下载:http://code.66 ...

随机推荐

  1. map & flatMap 浅析

    我之前一直以为我是懂 map 和 flatMap 的.但是直到我看到别人说:「一个实现了 flatMap 方法的类型其实就是 monad.」我又发现这个熟悉的东西变得陌生起来,本节烧脑体操打算更细致一 ...

  2. 栈的java实现和栈的应用

    [例子和习题出自数据结构(严蔚敏版), 本人使用java进行实现.  转载请注明作者和出处,  如有谬误, 欢迎在评论中指正. ] 栈的实现 栈是一种先进后出的数据结构, 首先定义了栈需要实现的接口: ...

  3. Android----->多线程的实现Thread、IntentService的运用

    首先建立一个Intent.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout x ...

  4. 4--OC --合成存取器方法

    1. 从OC 2.0开始就已经可以自动生成设置函数方法和获取函数方法(统称为存取器方法). 什么是 @property 和 @synthesize ? @property 和 @synthesize ...

  5. [原]JavaScript总结

    匿名函数 var ff = function () {             return 'hhqybsl';         };         var result = ff();      ...

  6. swift(2)元祖(Tuple)

    let somePoint = (, ) switch somePoint { , ): // 位于远点 println("(0, 0) is at the origin") ): ...

  7. IOS小工具以及精彩的博客

    IOS小工具以及精彩的博客 工具 Log Guru是一个收集Log的小工具, 可以在 Mac 上查看 iOS 设备的实时系统日志. 现在可以直接高亮显示在 FIR.im 上安装 app 失败的原因.后 ...

  8. 转博客至github

    呃呃呃,当初是从新浪博客转过来的,现在发现github的静态博客对我来说用起来更方便. 转至github,这里的东西以后有空会一点一点移过去. http://jcf94.github.io

  9. ratingbar设置不可调节星星数量

    <RatingBar android:id="@+id/rb_bar" android:layout_width="wrap_content" andro ...

  10. Oracle获取系统时间及格式化

    Oracle 获取当前日期及日期格式 获取系统日期:  SYSDATE()   格式化日期:     TO_CHAR(SYSDATE(),'YY/MM/DD HH24:MI:SS)           ...