(一)概述
手势是:连续触碰的行为,比如左右上下滑动屏幕,又或者画一些不规则的几何图形! Android对上述两种手势行为都提供了支持:

Android提供手势检测,并为手势识别提供了相应的监听器!
Android运行开发者自行添加手势,并且提供了相应的API识别用户手势!

如果你的手机是Android 4.x的原生Android系统的话,你可能可以在你的手机或者平板上看到谷歌 提供的一个Gesture Builder的APP,该应用允许用户以类似于涂鸦的方式绘制一个手写符号,使之 对应一个字符串名称!当然,没有这样的手机也没关系,我们有模拟器嘛,自己开个4.0的系统试试 就知道了,另外,我们可以到\mmt\sdcard\gestures获取到保存手势的文件!

(二)Gestures(手势)
1.Android中手势交互的执行顺序

    1.手指触碰屏幕时,触发MotionEvent事件!2.该事件被OnTouchListener监听,可在它的onTouch()方法中获得该MotionEvent对象!3.通过GestureDetector转发MotionEvent对象给OnGestureListener4.我们可以通过OnGestureListener获得该对象,然后获取相关信息,以及做相关处理!

我们来看下上述的三个类都是干嘛的: MotionEvent: 这个类用于封装手势、触摸笔、轨迹球等等的动作事件。 其内部封装了两个重要的属性X和Y,这两个属性分别用于记录横轴和纵轴的坐标。 GestureDetector: 识别各种手势。 OnGestureListener: 这是一个手势交互的监听接口,其中提供了多个抽象方法, 并根据GestureDetector的手势识别结果调用相对应的方法。

——上述资料摘自:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1020/448.html
2.GestureListener详解:

从1中我们知道了监听手势的关键是:GestureListener 他给我们提供了下述的回调方法:

    按下(onDown): 刚刚手指接触到触摸屏的那一刹那,就是触的那一下。抛掷(onFling): 手指在触摸屏上迅速移动,并松开的动作。长按(onLongPress): 手指按在持续一段时间,并且没有松开。滚动(onScroll): 手指在触摸屏上滑动。按住(onShowPress): 手指按在触摸屏上,它的时间范围在按下起效,在长按之前。抬起(onSingleTapUp):手指离开触摸屏的那一刹那。

知道了GestureListener的相关方法后,实现手势检测也很简单,步骤如下:

    Step 1: 创建GestureDetector对象,创建时需实现GestureListener传入Step 2: 将Activity或者特定组件上的TouchEvent的事件交给GestureDetector处理即可! 我们写个简单的代码来验证这个流程,即重写对应的方法:

代码如下:

public class MainActivity extends AppCompatActivity {private MyGestureListener mgListener;private GestureDetector mDetector;private final static String TAG = "MyGesture";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//实例化GestureListener与GestureDetector对象mgListener = new MyGestureListener();mDetector = new GestureDetector(this, mgListener);}@Overridepublic boolean onTouchEvent(MotionEvent event) {return mDetector.onTouchEvent(event);}//自定义一个GestureListener,这个是View类下的,别写错哦!!!private class MyGestureListener implements GestureDetector.OnGestureListener {@Overridepublic boolean onDown(MotionEvent motionEvent) {Log.d(TAG, "onDown:按下");return false;}@Overridepublic void onShowPress(MotionEvent motionEvent) {Log.d(TAG, "onShowPress:手指按下一段时间,不过还没到长按");}@Overridepublic boolean onSingleTapUp(MotionEvent motionEvent) {Log.d(TAG, "onSingleTapUp:手指离开屏幕的一瞬间");return false;}@Overridepublic boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {Log.d(TAG, "onScroll:在触摸屏上滑动");return false;}@Overridepublic void onLongPress(MotionEvent motionEvent) {Log.d(TAG, "onLongPress:长按并且没有松开");}@Overridepublic boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {Log.d(TAG, "onFling:迅速滑动,并松开");return false;}}}

对应操作截图:

PS:从上述结果来看,我们发现了一个问题: 我们实现OnGestureListener需要实现所有的手势,可能我针对的仅仅是滑动,但是你还是要去重载, 这显得很逗逼,是吧,官方肯定会给出解决方法滴,官方另外给我们提供了一个SimpleOnGestureListener类 只需把上述的OnGestureListener替换成SimpleOnGestureListener即可!

3.简单的例子:下滑关闭Activity,上滑启动新的Activity

这里就用上述的SimpleOnGestureListener来实现吧:

运行效果图:

实现代码:

public class MainActivity extends AppCompatActivity {private GestureDetector mDetector;private final static int MIN_MOVE = 200;   //最小距离private MyGestureListener mgListener;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//实例化SimpleOnGestureListener与GestureDetector对象mgListener = new MyGestureListener();mDetector = new GestureDetector(this, mgListener);}@Overridepublic boolean onTouchEvent(MotionEvent event) {return mDetector.onTouchEvent(event);}//自定义一个GestureListener,这个是View类下的,别写错哦!!!private class MyGestureListener extends GestureDetector.SimpleOnGestureListener {@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float v, float v1) {if(e1.getY() - e2.getY() > MIN_MOVE){startActivity(new Intent(MainActivity.this, MainActivity.class));Toast.makeText(MainActivity.this, "通过手势启动Activity", Toast.LENGTH_SHORT).show();}else if(e1.getY() - e2.getY()  < MIN_MOVE){finish();Toast.makeText(MainActivity.this,"通过手势关闭Activity",Toast.LENGTH_SHORT).show();}return true;}}}

结果分析: 从上面的对比就可以知道,相比起SimpleOnGestureListener使用SimpleOnGestureListener 显得更加的简单,想重写什么方法就重写什么方法,另外例子比较简单,大家可以自己试试 其他玩法,比如通过手势缩放图片~
4.手势添加与识别:

除了上面讲解的手势检测外,Android还运行我们将手势进行添加,然后提供了相关的识别API; Android中使用GestureLibrary来代表手势库,提供了GestureLibraries工具类来创建手势库!

四个加载手势库的静态方法:


获得GestureLibraries对象后,就可以使用该对象提供的下述方法来做相应操作了:

相关方法:

public void addGesture (String entryName, Gesture gesture):添加一个名为entryName的手势   public Set<String> getGestureEntries ():获得手势库中所有手势的名称  public ArrayList<Gesture> getGestures (String entryName):获得entryName名称对应的全部手势 public ArrayList<Prediction> recognize (Gesture gesture): 从当前手势库中识别与gesture匹配的全部手势
public void removeEntry (String entryName):删除手势库中entryName名称对应的手势 public void removeGesture (String entryName, Gesture gesture):删除手势库中entryName和gesture都匹配的手势 public abstract boolean save ():想手势库中添加手势或从中删除手势后调用该方法保存手势库

GestureOverlayView手势编辑组件:

Android为GestureOverlayView提供了三种监听器接口,如下,一般常用的是:OnGesturePerformedListener;用于手势完成时提供响应!

5.手势添加示例:
运行效果图:

好吧,下面贴下实现代码:

两个布局文件:activity_main.xml和dialog_save.xml

activity_main.xml

<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=".MainActivity"><TextView
        android:layout_width="match_parent"android:layout_height="wrap_content"android:text="请在下方屏幕中绘制手势~"android:textSize="20sp"/><!-- gestureStrokeType控制手势是否需要一笔完成,multiple表示允许多笔--><android.gesture.GestureOverlayView
        android:id="@+id/gesture"android:layout_width="match_parent"android:layout_height="match_parent"android:gestureStrokeType="multiple" /></LinearLayout>

dialog_save.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><LinearLayout
        android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextView
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginRight="8dp"android:text="请填写手势名称:"/><EditText
            android:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/edit_name"/></LinearLayout><ImageView
        android:id="@+id/img_show"android:layout_width="128dp"android:layout_height="128dp"android:layout_marginTop="10dp"/></LinearLayout>

MainActivity.java:

public class MainActivity extends AppCompatActivity {private EditText editText;private GestureOverlayView gesture;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//获取手势编辑组件后,设置相关参数gesture = (GestureOverlayView) findViewById(R.id.gesture);gesture.setGestureColor(Color.GREEN);gesture.setGestureStrokeWidth(5);gesture.addOnGesturePerformedListener(new GestureOverlayView.OnGesturePerformedListener() {@Overridepublic void onGesturePerformed(GestureOverlayView gestureOverlayView, final Gesture gesture) {View saveDialog = getLayoutInflater().inflate(R.layout.dialog_save,null,false);ImageView img_show = (ImageView) saveDialog.findViewById(R.id.img_show);final EditText edit_name = (EditText) saveDialog.findViewById(R.id.edit_name);Bitmap bitmap = gesture.toBitmap(128,128,10,0xffff0000);img_show.setImageBitmap(bitmap);new AlertDialog.Builder(MainActivity.this).setView(saveDialog).setPositiveButton("保存",new DialogInterface.OnClickListener(){@Overridepublic void onClick(DialogInterface dialogInterface, int i) {//获取文件对应的手势库GestureLibrary gestureLib = GestureLibraries.fromFile("/mnt/sdcard/mygestures");gestureLib.addGesture(edit_name.getText().toString(),gesture);gestureLib.save();}}).setNegativeButton("取消", null).show();}});}
}

最后还需要在AndroidManifest.xml中添加写入SD卡的权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

6.手势识别示例

实现代码:

public class MainActivity extends AppCompatActivity {private GestureOverlayView gesture;private GestureLibrary gestureLibrary;private Context mContext;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mContext = MainActivity.this;gestureLibrary = GestureLibraries.fromFile("mmt/sdcard/mygestures");if (gestureLibrary.load()) {Toast.makeText(mContext, "手势库加载成功", Toast.LENGTH_SHORT).show();} else {Toast.makeText(mContext, "手势库加载失败", Toast.LENGTH_SHORT).show();}//获取手势编辑组件后,设置相关参数gesture = (GestureOverlayView) findViewById(R.id.gesture);gesture.setGestureColor(Color.GREEN);gesture.setGestureStrokeWidth(5);gesture.addOnGesturePerformedListener(new GestureOverlayView.OnGesturePerformedListener() {@Overridepublic void onGesturePerformed(GestureOverlayView gestureOverlayView, final Gesture gesture) {//识别用户刚绘制的手势ArrayList<Prediction> predictions = gestureLibrary.recognize(gesture);ArrayList<String> result = new ArrayList<String>();//遍历所有找到的Prediction对象for (Prediction pred : predictions) {if (pred.score > 2.0) {result.add("与手势【" + pred.name + "】相似度为" + pred.score);}}if (result.size() > 0) {ArrayAdapter<Object> adapter = new ArrayAdapter<Object>(mContext,android.R.layout.simple_dropdown_item_1line, result.toArray());new AlertDialog.Builder(mContext).setAdapter(adapter,null).setPositiveButton("确定",null).show();}else{Toast.makeText(mContext,"无法找到匹配的手势!",Toast.LENGTH_SHORT).show();}}});}
}

另外别忘了在AndroidManifest.xml文件中加入读SD卡的权限:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

本节介绍了Android中的Gesture手势,讲解了手势判断,手势添加,手势识别三个内容;

事件处理机制之Gestures(手势)相关推荐

  1. Android平台的事件处理机制和手指滑动例子

    Android平台的事件处理机制有两种 基于回调机制的事件处理:Android平台中,每个View都有自己的处理事件的回调方法,开发人员可以通过重写View中的这些回调方法来实现需要的响应事件. 基于 ...

  2. java事件处理模型_从零开始理解JAVA事件处理机制(3)

    我们连续写了两小节的教师-学生的例子,必然觉得无聊死了,这样的例子我们就是玩上100遍,还是不知道该怎么写真实的代码.那从本节开始,我们开始往真实代码上面去靠拢. 事件最容易理解的例子是鼠标事件:我们 ...

  3. ​iOS的界面触摸事件处理机制,然后用一个实例来说明下应用场景.

    2019独角兽企业重金招聘Python工程师标准>>> 主要是记录下iOS的界面触摸事件处理机制,然后用一个实例来说明下应用场景. 一.处理机制 界面响应消息机制分两块,(1)首先在 ...

  4. Android中的事件处理机制

    Android提供了强大的事件处理机制,它包括两套处理机制: 1.基于监听的事件处理 2.基于回调的事件处理 对于Android基于监听的事件处理,主要的做法是为Android界面组件绑定特定的事件监 ...

  5. QT开发(十二)——QT事件处理机制

    一.QT事件简介 QT程序是事件驱动的, 程序的每个动作都是由内部某个事件所触发.QT事件的发生和处理成为程序运行的主线,存在于程序整个生命周期. 常见的QT事件类型如下: 键盘事件: 按键按下和松开 ...

  6. Android基于监听的事件处理机制

    Android提供了强大的事件处理机制,主要包括两大类: 1,基于监听的事件处理机制:主要做法是为Android界面组件绑定特定的事件监听器 2,基于回调的事件处理机制:主要做法是重写Android组 ...

  7. Cocos2d-JS事件处理机制

    在很多图形用户技术中,事件处理机制一般都有三个重要的角色:事件.事件源和事件处理者.事件源是事件发生的场所,通常就是各个视图或控件,事件处理者是接收事件并对其进行处理的一段程序. 事件处理机制中三个角 ...

  8. Qt 事件处理机制-qt源码解读

    在Qt中,事件被封装成一个个对象,所有的事件均继承自抽象类QEvent. 接下来依次谈谈Qt中有谁来产生.分发.接受和处理事件. 本篇来介绍Qt 事件处理机制.深入了解事件处理系统对于每个学习Qt人来 ...

  9. C#委托及事件处理机制浅析

       事件可以理解为某个对象所发出的消息,以通知特定动作(行为)的发生或状态的改变.行为的发生可能是来自用户交互,如鼠标点击:也可能源自其它的程序逻辑.在这里,触发事件的对象被称为事件(消息)发出者( ...

最新文章

  1. HTML5适应旧的浏览器的使用总结
  2. SAP Spartacus Set Active BaseSite action执行的时间点 - Route路由触发方式
  3. flask html新增,如何在script里修改flask传入html的变量?
  4. 网页制作小技巧:dl dt dd标签用法
  5. DotNetNuke 4/5 安装提示 msajax错误,下载AJAX 1.0即可解决
  6. 冲浪科技获Ventech China数百万美元天使轮融资,发力自动驾驶行业
  7. 百度离线地图瓦片下载
  8. 佩服Google敏锐和创意!人肉搜索引擎志愿者招募
  9. 商城小程序上新的物流助手功能,可以为商家运营带来什么帮助?
  10. Indy TCP/IP 组件里的几个常用方法
  11. 李若彤揭秘退隐10年原因:感情不顺 父亲离世 曾患抑郁症
  12. 互联网晚报 | 9月15日 星期三 | iPhone 13正式发布;天猫双11正式启动商家报名;华为推出鸿蒙矿山操作系统“矿鸿”...
  13. Postgresql skip locked跳过行锁消除行锁冲突等待
  14. 五大学科竞赛奖项&106所综合评价院校对照表(分省统计)
  15. 技嘉的UEFI修复windows与Ubuntu双系统引导+老毛桃修复引导失败+No EFI system partition was found.
  16. 华为正式发布方舟编译器,相关源码已开放下载;微软开源量子开发工具包 QDK;GitHub回应突然断供:也很无可奈何的样子……...
  17. 运维文档管理规范标准
  18. 使用vimdiff做git的diff与merge工具
  19. (读书笔记)中级语法-简单句和复杂句
  20. iOS开发 --- 开发工具

热门文章

  1. idea ubuntu 与 快捷键冲突_解除Intellij Idea中的热键冲突
  2. 【深度学习】卡通动漫人脸检测
  3. android camera慢动作,motion camera app安卓版
  4. c语言1076 wifi密码(15分),1076 Wifi密码 (15 分)
  5. 多机多GPU分布式计算
  6. 论大规模分布式系统缓存设计策略
  7. ES优化文件系统缓存filesystem cache
  8. 【NOI P模拟赛】序列题 (二分)
  9. 西安石油大学2023年第三届里奇杯编程大赛(初赛)
  10. spark如何进行聚类可视化_基于Spark的出租车轨迹处理与可视化平台