Android L(5.0)源码之手势识别GestureDetector
本人新手,最近下了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的更多相关文章
- [Android FrameWork 6.0源码学习] View的重绘过程之WindowManager的addView方法
博客首页:http://www.cnblogs.com/kezhuang/p/关于Activity的contentView的构建过程,我在我的博客中已经分析过了,不了解的可以去看一下<[Andr ...
- [Android FrameWork 6.0源码学习] LayoutInflater 类分析
LayoutInflater是用来解析XML布局文件,然后生成对象的ViewTree的工具类.是这个工具类的存在,才能让我们写起Layout来那么省劲. 我们接下来进去刨析,看看里边的奥秘 //调用i ...
- [Android FrameWork 6.0源码学习] View的重绘过程之Draw
View绘制的三部曲,测量,布局,绘画现在我们分析绘画部分测量和布局 在前两篇文章中已经分析过了.不了解的可以去我的博客里找一下 下面进入正题,开始分析调用以及函数原理 private void pe ...
- [Android FrameWork 6.0源码学习] ViewGroup的addView函数分析
Android中整个的View的组装是采用组合模式. ViewGroup就相当与树根,各种Layout就相当于枝干,各种子View,就相当于树叶. 至于View类.我们就当它是个种子吧.哈哈! Vie ...
- [Android FrameWork 6.0源码学习] View的重绘过程
View绘制的三部曲, 测量,布局,绘画今天我们分析测量过程 view的测量是从ViewRootImpl发起的,View需要重绘,都是发送请求给ViewRootImpl,然后他组织重绘在重绘的过程中 ...
- [Android FrameWork 6.0源码学习] Window窗口类分析
了解这一章节,需要先了解LayoutInflater这个工具类,我以前分析过:http://www.cnblogs.com/kezhuang/p/6978783.html Window是Activit ...
- [Android FrameWork 6.0源码学习] View的重绘过程之Layout
View绘制的三部曲,测量,布局,绘画现在我们分析布局部分测量部分在上篇文章中已经分析过了.不了解的可以去我的博客里找一下 View的布局和测量一样,都是从ViewRootImpl中发起,ViewRo ...
- [Android FrameWork 6.0源码学习] View的重绘ViewRootImpl的setView方法
博客首页:http://www.cnblogs.com/kezhuang/p/ 本篇文章来分析一下WindowManager的后续工作,也就是ViewRootImpl的setView函数的工作 /i* ...
- Android音乐播放器源码(歌词.均衡器.收藏.qq5.0菜单.通知)
一款Android音乐播放器源码,基本功能都实现了 qq5.0菜单(歌词.均衡器.收藏.qq5.0菜单.通知) 只有向右滑动出现,菜单键和指定按钮都还没有添加. 源码下载:http://code.66 ...
随机推荐
- PHP显示超全局变量和显示程序执行时间
<?php header('Content-type: text/html; charset=utf-8'); $t1 = microtime(true);//记录脚本刚开始运行是的时间戳 ec ...
- Spark集群搭建中的问题
参照<Spark实战高手之路>学习的,书籍电子版在51CTO网站 资料链接 Hadoop下载[链接](http://archive.apache.org/dist/hadoop/core/ ...
- hdu 2647 Reward(拓扑排序,反着来)
Reward Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Submis ...
- 如何让Spring MVC接收的参数可以转换为java对象
场景: web.xml中增加了一个DispatcherServlet配置,并在同级目录下添加了**-servlert.xml文件,搭建起了一个spring mvc的restful访问接口. 问题描述: ...
- 6-SUPER关键字
(1)强行调用父类方法的执行(2)super不一定在重写中使用,也可以表示那些方法是从父类中继承而来的.
- Android Studio 简单介绍和使用问题小结
原文 http://www.cnphp6.com/archives/59264 主题 Gradle Android Studio Android 随着android 5.0 的发布,android ...
- json中文乱码问题
首先在 tomcat的 D:\apache-tomcat-7.0.57\conf\server.xml里添加中文编码 <Connector port="8080" proto ...
- Android media媒体库分析之:MediaProvider
在做Android媒体应用程序时(Audio.Image.Video)需要对Android的媒体提供者(MediaProvider)做详细的分析,下面记录一下我的收获: 一.获取MediaProvid ...
- StretchAnimation伸缩动画.
原理是继承animation 然后改变他的margintop 和marginbottom 形成2个效果 ExpandTopAnimation public class ExpandTopAnim ...
- java dom4j解析xml实例(2)
java利用dom4j解析xml 需要的jar包: dom4j官方网站在 http://www.dom4j.org/ 下载dom4j-1.6.1.zip 解开后有两个包,仅操作XML文档的话把dom4 ...