手势识别官方教程(2)识别常见手势用GestureDetector+手势回调接口/手势抽象类
简介
GestureDetector识别手势。
GestureDetector.OnGestureListener是识别手势后的回调接口。
GestureDetector.SimpleOnGestureListener是抽象类。
基本步骤:
- 构造GestureDetector,注意要传入context和listener(GestureDetector.OnGestureListener或GestureDetector.SimpleOnGestureListener)
- 在Activity/View的onTouchEvent或onTouchEventListener回调中,调用mDetector.onTouchEvent(event);
- 处理手势成功识别后的回调,如onFling()
Detecting Common Gestures
A "touch gesture" occurs when a user places one or more fingers on the touch screen, and your application interprets that pattern of touches as a particular gesture. There are correspondingly two phases to gesture detection:
手势识别分两步:
- 截取到touch事件
- 分析它是否是支持的手势
- Gathering data about touch events.
- Interpreting the data to see if it meets the criteria for any of the gestures your app supports.
Support Library Classes
The examples in this lesson use the GestureDetectorCompat
and MotionEventCompat
classes. These classes are in the Support Library. You should use Support Library classes where possible to provide compatibility with devices running Android 1.6 and higher. Note that MotionEventCompat
is not a replacement for the MotionEvent
class. Rather, it provides static utility methods to which you pass your MotionEvent
object in order to receive the desired action associated with that event.
注意 GestureDetectorCompat 和 MotionEventCompat是扩展库里的,并且MotionEventCompat 也不是用来替换 MotionEvent 的。
1.Gather Data 截取touch事件的两种方法
When a user places one or more fingers on the screen, this triggers the callback onTouchEvent()
on the View that received the touch events. For each sequence of touch events (position, pressure, size, addition of another finger, etc.) that is ultimately identified as a gesture, onTouchEvent()
is fired several times.
The gesture starts when the user first touches the screen, continues as the system tracks the position of the user's finger(s), and ends by capturing the final event of the user's fingers leaving the screen. Throughout this interaction, the MotionEvent
delivered to onTouchEvent()
provides the details of every interaction. Your app can use the data provided by the MotionEvent
to determine if a gesture it cares about happened.
识别手势都是从触摸事件开始,有两种处理触摸事件的方法: 1,直接处理法:在activity和view(含自定义)重写onTouchEvent()方法
2,回调法:给已经封装好的view设置一个View.OnTouchListener重写onTouch()方法
1.1 Capturing touch events for an Activity or View
To intercept touch events in an Activity or View, override the onTouchEvent()
callback.
The following snippet uses getActionMasked()
to extract the action the user performed from the event
parameter. This gives you the raw data you need to determine if a gesture you care about occurred:
public class MainActivity extends Activity {
...
// This example shows an Activity, but you would use the same approach if
// you were subclassing a View.
@Override
public boolean onTouchEvent(MotionEvent event){ int action = MotionEventCompat.getActionMasked(event); switch(action) {
case (MotionEvent.ACTION_DOWN) :
Log.d(DEBUG_TAG,"Action was DOWN");
return true;
case (MotionEvent.ACTION_MOVE) :
Log.d(DEBUG_TAG,"Action was MOVE");
return true;
case (MotionEvent.ACTION_UP) :
Log.d(DEBUG_TAG,"Action was UP");
return true;
case (MotionEvent.ACTION_CANCEL) :
Log.d(DEBUG_TAG,"Action was CANCEL");
return true;
case (MotionEvent.ACTION_OUTSIDE) :
Log.d(DEBUG_TAG,"Movement occurred outside bounds " +
"of current screen element");
return true;
default :
return super.onTouchEvent(event);
}
}
You can then do your own processing on these events to determine if a gesture occurred. This is the kind of processing you would have to do for a custom gesture. However, if your app uses common gestures such as double tap, long press, fling, and so on, you can take advantage of the GestureDetector
class.GestureDetector
makes it easy for you to detect common gestures without processing the individual touch events yourself. This is discussed below in Detect Gestures.
1.2 Capturing touch events for a single view
As an alternative to onTouchEvent()
, you can attach an View.OnTouchListener
object to any View
object using the setOnTouchListener()
method. This makes it possible to to listen for touch events without subclassing an existing View
. For example:
View myView = findViewById(R.id.my_view);
myView.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
// ... Respond to touch events
return true;
}
});
Beware of creating a listener that returns false
for the ACTION_DOWN
event. If you do this, the listener will not be called for the subsequent ACTION_MOVE
and ACTION_UP
string of events. This is because ACTION_DOWN
is the starting point for all touch events.
If you are creating a custom View, you can override onTouchEvent()
, as described above.
2.Detect Gestures开始分析识别手势
Android provides the GestureDetector
class for detecting common gestures. Some of the gestures it supports include onDown()
, onLongPress()
, onFling()
, and so on. You can use GestureDetector
in conjunction with the onTouchEvent()
method described above.
GestureDetector 封装了常用的手势并心回调的方式通知已经识别的手势,如Down,LongPress,FLing,Scroll等。见: GestureDetector.OnGestureListener注意要在 onTouchEvent()中调用 GestureDetector.onTouchEvent(xxx); 才能识别手势。
2.1 Detecting All Supported Gestures
When you instantiate a GestureDetectorCompat
object, one of the parameters it takes is a class that implements the GestureDetector.OnGestureListener
interface.GestureDetector.OnGestureListener
notifies users when a particular touch event has occurred. To make it possible for your GestureDetector
object to receive events, you override the View or Activity's onTouchEvent()
method, and pass along all observed events to the detector instance.
In the following snippet, a return value of true
from the individual on<TouchEvent>
methods indicates that you have handled the touch event. A return value of false
passes events down through the view stack until the touch has been successfully handled.
注意 TouchEvent()的返回值,返回true表示在本函数中处理了,false表示本函数没有处理,那么事件继续传
Run the following snippet to get a feel for how actions are triggered when you interact with the touch screen, and what the contents of the MotionEvent
are for each touch event. You will realize how much data is being generated for even simple interactions.
public class MainActivity extends Activity implements
GestureDetector.OnGestureListener,
GestureDetector.OnDoubleTapListener{ private static final String DEBUG_TAG = "Gestures";
private GestureDetectorCompat mDetector; // Called when the activity is first created.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Instantiate the gesture detector with the
// application context and an implementation of
// GestureDetector.OnGestureListener
mDetector = new GestureDetectorCompat(this,this);
// Set the gesture detector as the double tap
// listener.
mDetector.setOnDoubleTapListener(this);
} @Override
public boolean onTouchEvent(MotionEvent event){
this.mDetector.onTouchEvent(event);
// Be sure to call the superclass implementation
return super.onTouchEvent(event);
} @Override
public boolean onDown(MotionEvent event) {
Log.d(DEBUG_TAG,"onDown: " + event.toString());
return true;
} @Override
public boolean onFling(MotionEvent event1, MotionEvent event2,
float velocityX, float velocityY) {
Log.d(DEBUG_TAG, "onFling: " + event1.toString()+event2.toString());
return true;
} @Override
public void onLongPress(MotionEvent event) {
Log.d(DEBUG_TAG, "onLongPress: " + event.toString());
} @Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
Log.d(DEBUG_TAG, "onScroll: " + e1.toString()+e2.toString());
return true;
} @Override
public void onShowPress(MotionEvent event) {
Log.d(DEBUG_TAG, "onShowPress: " + event.toString());
} @Override
public boolean onSingleTapUp(MotionEvent event) {
Log.d(DEBUG_TAG, "onSingleTapUp: " + event.toString());
return true;
} @Override
public boolean onDoubleTap(MotionEvent event) {
Log.d(DEBUG_TAG, "onDoubleTap: " + event.toString());
return true;
} @Override
public boolean onDoubleTapEvent(MotionEvent event) {
Log.d(DEBUG_TAG, "onDoubleTapEvent: " + event.toString());
return true;
} @Override
public boolean onSingleTapConfirmed(MotionEvent event) {
Log.d(DEBUG_TAG, "onSingleTapConfirmed: " + event.toString());
return true;
}
}
2.2 Detecting a Subset of Supported Gestures
If you only want to process a few gestures, you can extend GestureDetector.SimpleOnGestureListener
instead of implementing the GestureDetector.OnGestureListener
interface.
GestureDetector.SimpleOnGestureListener
provides an implementation for all of the on<TouchEvent>
methods by returning false
for all of them. Thus you can override only the methods you care about. For example, the snippet below creates a class that extends GestureDetector.SimpleOnGestureListener
and overrides onFling()
and onDown()
.
GestureDetector.SimpleOnGestureListener 是个使用起来比GestureDetector.OnGestureListener简单手势回调的接口,可只实现感举的手势。
Whether or not you use GestureDetector.OnGestureListener
, it's best practice to implement an onDown()
method that returns true
. This is because all gestures begin with an onDown()
message. If you return false
from onDown()
, as GestureDetector.SimpleOnGestureListener
does by default, the system assumes that you want to ignore the rest of the gesture, and the other methods of GestureDetector.OnGestureListener
never get called. This has the potential to cause unexpected problems in your app. The only time you should return false
from onDown()
is if you truly want to ignore an entire gesture.
public class MainActivity extends Activity { private GestureDetectorCompat mDetector; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDetector = new GestureDetectorCompat(this, new MyGestureListener());
} @Override
public boolean onTouchEvent(MotionEvent event){
this.mDetector.onTouchEvent(event);
return super.onTouchEvent(event);
} class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
private static final String DEBUG_TAG = "Gestures"; @Override
public boolean onDown(MotionEvent event) {
Log.d(DEBUG_TAG,"onDown: " + event.toString());
return true;
} @Override
public boolean onFling(MotionEvent event1, MotionEvent event2,
float velocityX, float velocityY) {
Log.d(DEBUG_TAG, "onFling: " + event1.toString()+event2.toString());
return true;
}
}
}
手势识别官方教程(2)识别常见手势用GestureDetector+手势回调接口/手势抽象类的更多相关文章
- 手势识别官方教程(7)识别缩放手势用ScaleGestureDetector.GestureDetector和ScaleGestureDetector.SimpleOnScaleGestureListener
Use Touch to Perform Scaling As discussed in Detecting Common Gestures, GestureDetector helps you de ...
- 手势识别官方教程(7)识别缩放手势用ScaleGestureDetector和SimpleOnScaleGestureListener
1.Use Touch to Perform Scaling As discussed in Detecting Common Gestures, GestureDetector helps you ...
- 手势识别官方教程(6)识别拖拽手势用GestureDetector.SimpleOnGestureListener和onTouchEvent
三种现实drag方式 1,在3.0以后可以直接用 View.OnDragListener (在onTouchEvent中调用某个view的startDrag()) 2,onTouchEvent() ...
- 手势识别官方教程(3)识别移动手势(识别速度用VelocityTracker)
moving手势在onTouchEvent()或onTouch()中就可识别,编程时主要是识别积云的速度用VelocityTracker等, Tracking Movement This lesson ...
- 手势识别官方教程(8)拦截触摸事件,得到触摸的属性如速度,距离等,控制view展开
onInterceptTouchEvent可在onTouchEvent()前拦截触摸事件, ViewConfiguration得到触摸的属性如速度,距离等, TouchDelegate控制view展开 ...
- 手势识别官方教程(4)在挑划或拖动手势后view的滚动用ScrollView和 HorizontalScrollView,自定义用Scroller或OverScroller
简单滚动用ScrollView和 HorizontalScrollView就够.自定义view时可能要自定义滚动效果,可以使用 Scroller或 OverScroller Animating a S ...
- Unity性能优化(3)-官方教程Optimizing garbage collection in Unity games翻译
本文是Unity官方教程,性能优化系列的第三篇<Optimizing garbage collection in Unity games>的翻译. 相关文章: Unity性能优化(1)-官 ...
- Unity性能优化(2)-官方教程Diagnosing performance problems using the Profiler window翻译
本文是Unity官方教程,性能优化系列的第二篇<Diagnosing performance problems using the Profiler window>的简单翻译. 相关文章: ...
- Unity性能优化(4)-官方教程Optimizing graphics rendering in Unity games翻译
本文是Unity官方教程,性能优化系列的第四篇<Optimizing graphics rendering in Unity games>的翻译. 相关文章: Unity性能优化(1)-官 ...
随机推荐
- xp 中的IIS安装成功之后,访问网页显示没有权限访问解决方法
在做xp的IIS发布网站时遇到一个问题就是当你访问网站的时候,显示没有权限访问网站,但是我已经开启了匿名访问网站了,怎么还没有权限访问呢?后来经过上网搜资料解决,当时很多网上都说没打开匿名访问,当时我 ...
- Lodop错误汇总
代码方面 需要修改 LodopFuncs.js 里面的src地址,主要是端口号,端口号需要和服务器里面的程序的端口一样.如下: 调试错误 可以通过查看调用lodop的地方,查看lodop是否为空( ...
- 懒人记录 Hadoop2.7.1 集群搭建过程
懒人记录 Hadoop2.7.1 集群搭建过程 2016-07-02 13:15:45 总结 除了配置hosts ,和免密码互连之外,先在一台机器上装好所有东西 配置好之后,拷贝虚拟机,配置hosts ...
- (转)boost::bind介绍
转自:http://www.cnblogs.com/sld666666/archive/2010/12/14/1905980.html 这篇文章介绍boost::bind()的用法, 文章的主要内容是 ...
- java.util.regx Demo
import java.util.regex.Matcher;import java.util.regex.Pattern; public class TestRegex { public stati ...
- Linux中的简单命令
history:打印你输过的命令 1.用户在shell中输入的命令会自动保存到内存缓冲区 2.在退出shell的时候,内存中的数据会刷新到磁盘文件:~/.bash_history ...
- C++字符串函数与C字符串函数比较
赋值拷贝: #include <iostream> #include <string> using namespace std; void main(){ string a=& ...
- RX学习笔记:正则表达式
正则表达式 2016-07-03 正则表达式是以字符串模板的形式匹配查找字符的方式. 正则表达式是字符串模板,所以其本身是一个字符串,首尾以反斜杆 / 开始和结束. 在两反斜杆中间的字符串表示要查找的 ...
- SQL Server2008数据库导入导出兼容性处理
使用场景:SQL Server 的高版本数据库恢复到低版本则可能会有兼容性问题,为了解决此类问题进行数据库脚本模式处理,数据库结构,及数据存储更换版本等. 1. 选择要导出的数据库,右键任务,生成脚 ...
- 创建一个cocos2d-x工程添加一个自定义Scene并显示
#include "cocos2d.h" class RunScene :public cocos2d::CCLayer { public: virtual bool init() ...