Android-----手势识别GestureDetector
2015-10-20 22:34
507 查看
手势操作原理
首先,在Android系统中,每一次手势交互都会依照以下顺序执行。
1. 接触接触屏一刹那,触发一个MotionEvent事件。
2. 该事件被OnTouchListener监听,在其onTouch()方法里获得该MotionEvent对象。
3. 通过GestureDetector(手势识别器)转发次MotionEvent对象至OnGestureListener。
4. OnGestureListener获得该对象,听根据该对象封装的的信息,做出合适的反馈。
手势操作类和接口
下面一同来了解一下MotionEvent、GestureDetector和OnGestureListener。
MotionEvent: 这个类用于封装手势、触摸笔、轨迹球等等的动作事件。其内部封装了两个重要的属性X和Y,这两个属性分别用于记录横轴和纵轴的坐标。
GestureDetector: 识别各种手势。
OnGestureListener: 这是一个手势交互的监听接口,其中提供了多个抽象方法,并根据GestureDetector的手势识别结果调用相对应的方法。
手势操作各个方法的含义
按下(onDown): 刚刚手指接触到触摸屏的那一刹那,就是触的那一下。
抛掷(onFling): 手指在触摸屏上迅速移动,并松开的动作。
长按(onLongPress): 手指按在持续一段时间,并且没有松开。
滚动(onScroll): 手指在触摸屏上滑动。
按住(onShowPress): 手指按在触摸屏上,它的时间范围在按下起效,在长按之前。
抬起(onSingleTapUp):手指离开触摸屏的那一刹那。
任何手势动作都会先执行一次按下(onDown)动作。
长按(onLongPress)动作前一定会执行一次按住(onShowPress)动作。
按住(onShowPress)动作和按下(onDown)动作之后都会执行一次抬起(onSingleTapUp)动作。
长按(onLongPress)、滚动(onScroll)和抛掷(onFling)动作之后都不会执行抬起(onSingleTapUp)动作。
通过GestureDetector.OnGestureListener来获取当前被触发的操作手势(Single Tap Up、Show Press、Long Press、Scroll、Down、Fling),具体包括以下几种:
boolean onDoubleTap(MotionEvent e)
解释:双击的第二下Touch down时触发
boolean onDoubleTapEvent(MotionEvent e)
解释:双击的第二下Touch down和up都会触发,可用e.getAction()区分。
boolean onDown(MotionEvent e)
解释:Touch down时触发
boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
解释:Touch了滑动一点距离后,up时触发。
void onLongPress(MotionEvent e)
解释:Touch了不移动一直Touch down时触发
boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
解释:Touch了滑动时触发。
void onShowPress(MotionEvent e)
解释:Touch了还没有滑动时触发
(与onDown,onLongPress比较 onDown只要Touch down一定立刻触发。而Touchdown后过一会没有滑动先触发onShowPress再是onLongPress。
所以Touchdown后一直不滑动,onDown->onShowPress->onLongPress这个顺序触发。)
boolean onSingleTapConfirmed(MotionEvent e)
boolean onSingleTapUp(MotionEvent e)
解释:上面这两个函数都是在touch down后又没有滑动(onScroll),又没有长按(onLongPress),然后Touchup时触发。
点击一下非常快的(不滑动)Touchup:
onDown->onSingleTapUp->onSingleTapConfirmed
点击一下稍微慢点的(不滑动)Touchup:
onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed
例子
按如下的动作执行:单击---->双击---->拖拽---->长按
logcat打印的信息如下:
手势识别的例子
导入系统自带的GestureBuilder,该项目在Android的sdk下的samples中,具体路径\Android\android-sdk\samples\android-8
添加对应的手势
在sdcard下生成gesture,将其copy到你的项目中的raw文件中
布局文件:
注意:android.gesture.GestureOverlayView是系统自带的,包名要写全
android:gestureStrokeType="multiple" // multiple多笔 single单笔
Java代码
实现的功能:
识别“v”,关闭当前的应用;
识别“c”,拨打指定的电话号码;
识别“x”,显示一条toast信息。
运行效果:
代码下载地址:http://download.csdn.net/detail/dangnianmingyue_gg/9198067
首先,在Android系统中,每一次手势交互都会依照以下顺序执行。
1. 接触接触屏一刹那,触发一个MotionEvent事件。
2. 该事件被OnTouchListener监听,在其onTouch()方法里获得该MotionEvent对象。
3. 通过GestureDetector(手势识别器)转发次MotionEvent对象至OnGestureListener。
4. OnGestureListener获得该对象,听根据该对象封装的的信息,做出合适的反馈。
手势操作类和接口
下面一同来了解一下MotionEvent、GestureDetector和OnGestureListener。
MotionEvent: 这个类用于封装手势、触摸笔、轨迹球等等的动作事件。其内部封装了两个重要的属性X和Y,这两个属性分别用于记录横轴和纵轴的坐标。
GestureDetector: 识别各种手势。
OnGestureListener: 这是一个手势交互的监听接口,其中提供了多个抽象方法,并根据GestureDetector的手势识别结果调用相对应的方法。
手势操作各个方法的含义
按下(onDown): 刚刚手指接触到触摸屏的那一刹那,就是触的那一下。
抛掷(onFling): 手指在触摸屏上迅速移动,并松开的动作。
长按(onLongPress): 手指按在持续一段时间,并且没有松开。
滚动(onScroll): 手指在触摸屏上滑动。
按住(onShowPress): 手指按在触摸屏上,它的时间范围在按下起效,在长按之前。
抬起(onSingleTapUp):手指离开触摸屏的那一刹那。
任何手势动作都会先执行一次按下(onDown)动作。
长按(onLongPress)动作前一定会执行一次按住(onShowPress)动作。
按住(onShowPress)动作和按下(onDown)动作之后都会执行一次抬起(onSingleTapUp)动作。
长按(onLongPress)、滚动(onScroll)和抛掷(onFling)动作之后都不会执行抬起(onSingleTapUp)动作。
通过GestureDetector.OnGestureListener来获取当前被触发的操作手势(Single Tap Up、Show Press、Long Press、Scroll、Down、Fling),具体包括以下几种:
boolean onDoubleTap(MotionEvent e)
解释:双击的第二下Touch down时触发
boolean onDoubleTapEvent(MotionEvent e)
解释:双击的第二下Touch down和up都会触发,可用e.getAction()区分。
boolean onDown(MotionEvent e)
解释:Touch down时触发
boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
解释:Touch了滑动一点距离后,up时触发。
void onLongPress(MotionEvent e)
解释:Touch了不移动一直Touch down时触发
boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
解释:Touch了滑动时触发。
void onShowPress(MotionEvent e)
解释:Touch了还没有滑动时触发
(与onDown,onLongPress比较 onDown只要Touch down一定立刻触发。而Touchdown后过一会没有滑动先触发onShowPress再是onLongPress。
所以Touchdown后一直不滑动,onDown->onShowPress->onLongPress这个顺序触发。)
boolean onSingleTapConfirmed(MotionEvent e)
boolean onSingleTapUp(MotionEvent e)
解释:上面这两个函数都是在touch down后又没有滑动(onScroll),又没有长按(onLongPress),然后Touchup时触发。
点击一下非常快的(不滑动)Touchup:
onDown->onSingleTapUp->onSingleTapConfirmed
点击一下稍微慢点的(不滑动)Touchup:
onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed
例子
package com.gjg.gesturedemo; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.GestureDetector; import android.view.GestureDetector.SimpleOnGestureListener; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.widget.Button; public class OtherActivity extends Activity implements OnTouchListener { private Button mButton = null; GestureDetector mGesture = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.other); Log.i("TEST", "onCreate"); mButton = (Button) findViewById(R.id.button1); mButton.setOnTouchListener(this); mGesture = new GestureDetector(this, new GestureListener()); } @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub return mGesture.onTouchEvent(event); } class GestureListener extends SimpleOnGestureListener { @Override public boolean onDoubleTap(MotionEvent e) { // TODO Auto-generated method stub Log.i("TEST", "onDoubleTap"); return super.onDoubleTap(e); } @Override public boolean onDown(MotionEvent e) { // TODO Auto-generated method stub Log.i("TEST", "onDown"); return super.onDown(e); } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { // TODO Auto-generated method stub Log.i("TEST", "onFling:velocityX = " + velocityX + " velocityY" + velocityY); return super.onFling(e1, e2, velocityX, velocityY); } @Override public void onLongPress(MotionEvent e) { // TODO Auto-generated method stub Log.i("TEST", "onLongPress"); super.onLongPress(e); } @Override public void onShowPress(MotionEvent e) { // TODO Auto-generated method stub Log.i("TEST", "onShowPress"); super.onShowPress(e); } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // TODO Auto-generated method stub Log.i("TEST", "onScroll:distanceX = " + distanceX + " distanceY = " + distanceY); return super.onScroll(e1, e2, distanceX, distanceY); } @Override public boolean onSingleTapUp(MotionEvent e) { // TODO Auto-generated method stub Log.i("TEST", "onSingleTapUp"); return super.onSingleTapUp(e); } } }
按如下的动作执行:单击---->双击---->拖拽---->长按
logcat打印的信息如下:
手势识别的例子
导入系统自带的GestureBuilder,该项目在Android的sdk下的samples中,具体路径\Android\android-sdk\samples\android-8
添加对应的手势
在sdcard下生成gesture,将其copy到你的项目中的raw文件中
布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.gjg.gesturedemo.MainActivity" > <android.gesture.GestureOverlayView android:id="@+id/gesture" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:background="#000000" android:gestureStrokeType="multiple" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/recoginze" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="recongize" android:text="@string/recognize" /> </LinearLayout> </LinearLayout>
注意:android.gesture.GestureOverlayView是系统自带的,包名要写全
android:gestureStrokeType="multiple" // multiple多笔 single单笔
Java代码
实现的功能:
识别“v”,关闭当前的应用;
识别“c”,拨打指定的电话号码;
识别“x”,显示一条toast信息。
package com.gjg.gesturedemo; import java.util.ArrayList; import android.app.Activity; import android.content.Intent; import android.gesture.Gesture; import android.gesture.GestureLibraries; import android.gesture.GestureLibrary; import android.gesture.GestureOverlayView; import android.gesture.GestureOverlayView.OnGestureListener; import android.gesture.GestureOverlayView.OnGesturePerformedListener; import android.gesture.Prediction; import android.net.Uri; import android.os.Bundle; import android.os.Process; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.Toast; public class MainActivity extends Activity { public static String Tag="MainActivity"; private GestureLibrary library; private Gesture gesture; private GestureOverlayView overlayView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //得到手势库 library=GestureLibraries.fromRawResource(this, R.raw.gestures); //加载手势库 library.load(); overlayView =(GestureOverlayView) findViewById(R.id.gesture); //适用于单笔手势 //overlayView.addOnGesturePerformedListener(new GesturePerformedListener()); //单笔和多笔都适用 overlayView.addOnGestureListener(new GestureListener()); } public void recongize(View v){ recognizedGesture(gesture); overlayView.clear(true); } private final class GestureListener implements OnGestureListener{ @Override public void onGestureStarted(GestureOverlayView overlay, MotionEvent event) { Log.e(Tag, "onGestureStarted"); } @Override public void onGesture(GestureOverlayView overlay, MotionEvent event) { Log.e(Tag, "onGesture"); } @Override public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) { Log.e(Tag, "onGestureEnded"); //得到最后画完的手势 gesture=overlay.getGesture(); } @Override public void onGestureCancelled(GestureOverlayView overlay, MotionEvent event) { Log.e(Tag, "onGestureCancelled"); } } private final class GesturePerformedListener implements OnGesturePerformedListener{ @Override public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { recognizedGesture(gesture); } } private void recognizedGesture(Gesture gesture) { //得到手势集合,最匹配的放在集合的第一条 ArrayList<Prediction> predictions=library.recognize(gesture); if(!predictions.isEmpty()){ //得到第一个匹配值 Prediction prediction=predictions.get(0); //匹配值:0<val<=10 1:10%的相似度 if(prediction.score>=6){ if("callPhone".equals(prediction.name)){ Intent intent=new Intent(Intent.ACTION_CALL,Uri.parse("tel:13727150778")); startActivity(intent); }else if("closeActivity".equals(prediction.name)){ finish(); }else if("showMessage".equals(prediction.name)){ Toast.makeText(this, "hello world!", 1).show(); } }else{ Toast.makeText(MainActivity.this, "匹配度太低", 1).show(); } }else{ Toast.makeText(MainActivity.this, "不匹配", 1).show(); } } @Override protected void onDestroy() { super.onDestroy(); Process.killProcess(Process.myPid()); } }
运行效果:
代码下载地址:http://download.csdn.net/detail/dangnianmingyue_gg/9198067
相关文章推荐
- android使用gesturedetector手势识别示例分享
- 在Swift程序中实现手势识别的方法
- IOS初级教程2:UITapGestureRecognizer手势识别的简单使用
- Android手势库
- android手势操作滑动效果触摸屏事件处理
- Android Gesture Detector
- The Core iOS CookBook 第一章节学习笔记 - 手势和触控
- 实战1.2-利用手势识别器,实现视图的手势控制
- Android手势Gesture详解、、、
- Android Gesture Detector
- 导航控制器 手势识别不了
- a simple android user interface in java
- IOS 开发手势识别
- 转自原文地址:IOS UIScrollview UIImageView点击事件处理
- UITableView 与 UITapGesture 的一点疑惑与探讨
- ios自用学习笔记-触摸事件与手势识别
- 安卓(Android)surfaceview无法使用gesturedetector的解决办法
- OC笔记 - 事件处理(2015.4.3)
- 一个比较有前景的电脑应用程序构想
- ListView与手势识别不能正确响应的解决办法