android学习笔记52——手势Gesture,增加手势、识别手势
手势Gesture,增加手势
android除了提供了手势检测之外,还允许应用程序把用户手势(多个持续的触摸事件在屏幕上形成特定的形状)添加到指定文件中,以备以后使用
如果程序需要,当用户下次再次画出该手势时,系统将可识别该手势。
android使用GestureLibray来代替手势库,并提供了GestureLibraries工具类来创建手势库,GestureLibraries提供了如下4个静态方法从不同位置加载手势库。
1.static GestureLibray fromFile(String path):从path代表的文件中加载手势;
2.static GestureLibray fromFile(File path):从path代表的文件中加载手势;
3.static GestureLibray fromPrivateFile(Context context,String name):从指定应用程序的数据文件夹中name文件中加载手势库;
4.static GestureLibray fromRawResource(Context context, int resourceId):从resourceId所代表的资源中加载手势库。
一旦程序中获得了GestureLibray对象后,该对象提供如下方法来添加、识别手势:
1.void addGesture(String entryName,Gesture gesture):添加一个名为entryName的手势;
2.Set<String>getGestureEntries():获取该手势库中的所有手势的名称;
3.ArrayList<Gesture>getGestures(String entryName):获取entryName名称对应的所有手势;
4.ArrayList<Prediction>recognize(Gesture gesture):从当前手势库中识别与gesture匹配的全部手势;
5.void removeEntry(String entryName):删除手势库中entryName对应的手势;
6.void removeGesture(String entryName,Gesture gesture):删除手势库中entryName、gesture对应的手势;
7.boolean save():当手势库中听见手势或者删除手势后调用该方法保存手势库。
android提供了GestureLibraries、GestureLibrary来管理手势之外,还提供了一个专门的手势编辑组件——GestureOverlayView,该组件就像一个“绘图组件”,只是用户在组件上绘制的不是图像,而是手势。
为了监听GestureOverlayView组件上的手势,android为GestureOverlayView提供了OnGestureLinstener、OnGesturePerformedListener、OnGesturingListener三个监听器接口,这些监听器所包含的方法分别用于响应手势事件开始、结束、完成、取消等事件,开发者可根据实现需求来选择不同的监听器——一般来说,OnGesturePerformedListener是最常用的监听器,其用于在手势事件完成时提供响应。
注意:
GestureOverlayView不是标准的视图组件,在界面布局中使用该组件时,需要使用完全限定名称。
布局文件==》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="请在以下屏幕上绘制手势" />
<EditText
android:id="@+id/edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="110" />
<android.gesture.GestureOverlayView
android:id="@+id/gesture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gestureStrokeType="multiple" />
<!--
android:gestureStrokeType 用于控制手势是否需要多笔完成,大部分情况,
一个手势只需要一笔完成,此时可将该参数设置为Single;多笔完成则设为multiple
--> </LinearLayout> 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="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="8dip"
android:text="添加手势" /> <EditText
android:id="@+id/gestureName"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<!-- 定义一个图片框,用于显示手势 --> <ImageView
android:id="@+id/show"
android:layout_width="128dp"
android:layout_height="128dp"
android:layout_marginTop="10dp" /> </LinearLayout> 代码实现==》
package com.example.myaddgesture; import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.gesture.Gesture;
import android.gesture.GestureLibraries;
import android.gesture.GestureLibrary;
import android.gesture.GestureOverlayView;
import android.gesture.GestureOverlayView.OnGesturePerformedListener;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView; public class MainActivity extends Activity
{
EditText edit;
GestureOverlayView gestureView; @Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main); edit = (EditText) this.findViewById(R.id.gestureName);
// 获取手势编辑视图
gestureView = (GestureOverlayView) this.findViewById(R.id.gesture);
// 设置手势绘制颜色
gestureView.setGestureColor(Color.RED);
// 设置手势绘制的宽度
gestureView.setGestureStrokeWidth(10);
// 为手势完成事件绑定事件监听器——手势完成后,触发该事件
gestureView.addOnGesturePerformedListener(new OnGesturePerformedListener()
{
@Override
public void onGesturePerformed(GestureOverlayView overlay, final Gesture gesture)
{
Log.i("swg", "onGesturePerformed");
// 加载save.xml界面布局视图
View dialog = getLayoutInflater().inflate(R.layout.save, null);
ImageView image = (ImageView) dialog.findViewById(R.id.show);
final EditText gestureName = (EditText) dialog.findViewById(R.id.gestureName);
// 根据Gesture包含的手势创建一个位图
Bitmap bitmap = gesture.toBitmap(128, 128, 10, 0xFFFF0000);
image.setImageBitmap(bitmap);
// 使用对话框显示dialog组件
new AlertDialog.Builder(MainActivity.this).setView(dialog)
.setPositiveButton("保存", new OnClickListener()
{
@SuppressLint("SdCardPath")
@Override
public void onClick(DialogInterface dialog, int which)
{
Log.i("swg", "setPositiveButton-->onClick");
// 获取指定文件对应的手势库
GestureLibrary lib = GestureLibraries
.fromFile("/sdcard/mygestures");
lib.addGesture(gestureName.getText().toString(), gesture);
// 保存手势
lib.save();
}
}).setNegativeButton("取消", null).show();
}
});
} @Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} }
注意:需要多笔操作才可以弹出对话框。
运行效果如下:

识别用户手势
GestureLibray提供了额recognize(Gesture gesture)方法识别用户手势,该方法将会返回该手势库中所有与gesture参数匹配的手势——两个手势的图形越相似、相似度越高。
recognize(Gesture ges)方法返回值为ArrayList<Prediction>,其中Prediction封装了手势的匹配信息,Prediction对象的name属性代表了匹配的手势名,score属性代表了手势的相似度。
下面的程序将会利用以上添加手势库程序所创建的手势库来识别手势,如下所示:
布局文件==》
<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" > <android.gesture.GestureOverlayView
android:id="@+id/gesture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gestureStrokeType="multiple" />
<!--
android:gestureStrokeType 用于控制手势是否需要多笔完成,大部分情况,
一个手势只需要一笔完成,此时可将该参数设置为Single;多笔完成则设为multiple
--> </LinearLayout> 代码实现==》
package com.example.myrecognizegesture; import java.util.ArrayList; import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.gesture.Gesture;
import android.gesture.GestureLibraries;
import android.gesture.GestureLibrary;
import android.gesture.GestureOverlayView;
import android.gesture.GestureOverlayView.OnGesturePerformedListener;
import android.gesture.Prediction;
import android.graphics.Color;
import android.view.Menu;
import android.widget.ArrayAdapter;
import android.widget.Toast; public class MainActivity extends Activity
{
GestureOverlayView gestureView;
GestureLibrary gestureLib; @SuppressLint({ "SdCardPath", "ShowToast" })
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); gestureView = (GestureOverlayView) this.findViewById(R.id.gesture);
// 设置手势绘制颜色
gestureView.setGestureColor(Color.RED);
// 设置手势绘制的宽度
gestureView.setGestureStrokeWidth(10); gestureLib = GestureLibraries.fromFile("/sdcard/mygestures");
if (gestureLib.load())
Toast.makeText(MainActivity.this, "手势文件装载成功", 5000).show();
else
Toast.makeText(MainActivity.this, "手势文件装载失败", 5000).show(); gestureView.addOnGesturePerformedListener(new OnGesturePerformedListener()
{
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture)
{
// 识别用户刚刚绘制的手势
ArrayList<Prediction> predictions = gestureLib.recognize(gesture);
ArrayList<String> result = new ArrayList<String>();
// 遍历所有找到的Prediction对象
for (Prediction pred : predictions)
{
// 输出相似度大于2.0的手势
if (pred.score > 2)
result.add("与手势[" + pred.name + "]相似度为:" + pred.score);
if (result.size() > 0)
{
ArrayAdapter adapter = new ArrayAdapter(MainActivity.this,
android.R.layout.simple_dropdown_item_1line, result.toArray());
new AlertDialog.Builder(MainActivity.this).setAdapter(adapter, null)
.setPositiveButton("保存", null).show();
} else
Toast.makeText(MainActivity.this, "无法找到匹配的手势", 5000).show();
}
}
});
} @Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} }
运行效果如下:(和实际连接手机运行存在一定差异,虚拟机部分内容显示不全)

android学习笔记52——手势Gesture,增加手势、识别手势的更多相关文章
- Android学习笔记之滑动翻页(屏幕切换)
如何实现手机上手动滑动翻页效果呢?呵呵,在这里我们就给你们介绍一下吧. 一般实现这个特效会用到一个控件:ViewFlipper <1>View切换的控件—ViewFlipper 这个控件是 ...
- Android学习笔记进阶之在图片上涂鸦(能清屏)
Android学习笔记进阶之在图片上涂鸦(能清屏) 2013-11-19 10:52 117人阅读 评论(0) 收藏 举报 HandWritingActivity.java package xiaos ...
- 【转】 Pro Android学习笔记(七八):服务(3):远程服务:AIDL文件
目录(?)[-] 在AIDL中定义服务接口 根据AIDL文件自动生成接口代码 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.n ...
- 【转】 Pro Android学习笔记(七五):HTTP服务(9):DownloadManager
目录(?)[-] 小例子 保存在哪里下载文件信息设置和读取 查看下载状态和取消下载 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件,转载须注明出处:http://blog.csd ...
- 【转】 Pro Android学习笔记(五七):Preferences(1):ListPreference
目录(?)[-] 例子1ListPreference小例子 定义一个preferences XML文件 继承PreferenceActivity 用户定制偏好的读取 第一次运行时设置缺省值 设置Cat ...
- 【转】 Pro Android学习笔记(三三):Menu(4):Alternative菜单
目录(?)[-] 什么是Alternative menu替代菜单 小例子说明 Alternative menu代码 关于Category和规范代码写法 关于flags 多个匹配的itemId等参数 什 ...
- 【转】Pro Android学习笔记(三十):Menu(1):了解Menu
目录(?)[-] 创建Menu MenuItem的属性itemId MenuItem的属性groupId MenuItem的属性orderId MenuItem的属性可选属性 Menu触发 onOpt ...
- 【转】 Pro Android学习笔记(二九):用户界面和控制(17):include和merge
目录(?)[-] xml控件代码重用include xml控件代码重用merge 横屏和竖屏landsacpe portrait xml控件代码重用:include 如果我们定义一个控件,需要在不同的 ...
- 【转】Pro Android学习笔记(二三):用户界面和控制(11):其他控件
目录(?)[-] Chronometer计时器控件 倒计时CountDownTimer Switch控件 Space控件 其他控件 Android提供了很多控件,基本上都是view的扩展. Chron ...
随机推荐
- Java 中的 request 和response 理解
request和response(请求和响应) 1.当Web容器收到客户端的发送过来http请求,会针对每一次请求,分别创建一个用于代表此次请求的HttpServletRequest对象(reque ...
- ArrayList其实就那么一回事儿之源码浅析
ArrayList 算是常用的集合之一了,不知作为javaner的你有没在百忙之中抽出一点时间看看ArrayList的源码呢. 如果看了,你会觉得其实ArrayList其实就那么一回事儿,对吧,下面就 ...
- pwnable.kr-collision
题目: 链接后登陆 ssh col@pwnable.kr -p2222 查看文件以及权限 Ls –al 查看代码 cat col.c 根据 if(strlen(argv[1]) != 20){ pri ...
- Java中的泛型
1:泛型(掌握) (1)泛型概述 是一种把明确类型的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型. (2)格式: <数据类型> 注意:该数据类型只能是引用类型. (3)好处: ...
- Divisors
计算小于n的数中,约数个数最多的数,若有多个最输出最小的一个数. http://hihocoder.com/problemset/problem/1187 对于100有 60 = 2 * 2 * 3 ...
- Android Studio Reference local .aar files
repositories { flatDir { dirs 'libs' }} dependencies { compile 'com.android.support:support-v4:22.2. ...
- 【winform 学习】登录
一直都是做asp.net,没有做过winform项目,新建个项目后,就啥不会了,不知道从何下手. 简单的登录项目也不会,画了个登录界面后,就遇到了,跳入主界面后,怎样将登录界面关闭的问题. 在网上找到 ...
- UE4 异步资源加载
http://blog.csdn.net/pizi0475/article/details/48178861 http://blog.sina.com.cn/s/blog_710ea1400102vl ...
- ashx
一般处理程序(HttpHandler)是·NET众多web组件的一种,ashx是其扩展名.一个httpHandler接受并处理一个http请求,类比于Java中的servlet.类比于在Java中需要 ...
- KVC/KVO原理详解及编程指南
一.简介 1.KVC简介 2.KVO简介 二.KVC相关技术 1.Key和Key Path 2.点语法和KVC 3.一对多关系(To-Many)中的集合访问器方法 4.键值验证(Key-Value V ...