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 ...
随机推荐
- MCU厂家
新唐(nuvoton):http://www.nuvoton.com/义隆(emc):http://www.emc.com.tw/chs/遠翔(feeling):http://www.feeling- ...
- guava学习--Supplier Suppliers
转载:http://www.cnblogs.com/jun-ma/p/4850591.html Guava Suppliers的主要功能是创建包裹的单例对象,通过get方法可以获取对象的值.每次获取的 ...
- 使用urllib编写python爬虫
新版python中,urllib和urllib2合并了,统一为urllib (1)简单爬取网页 import urllib content = urllib.request.urlopen(req). ...
- UE3:SkeletalMesh的绘制流程
[目标] SkeletalMesh的绘制流程 [思路] 1 顶点缓冲流 静态数据流向 动态数据流向(紫红色箭头) 2 FGPUSkinVertexFactory.ShaderDataType.Bone ...
- HDU 2871 Memory Control
一共4种操作 其中用线段树 区间合并,来维护连续空的长度,和找出那个位置.其他用vector维护即可 #include<cstring> #include<cstdio> #i ...
- easyui 之ComboTree 用法Demo
实现效果如下: HTML部分: <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="ser ...
- enmo_day_03
安装 装载点 : /u01 (第一个挂载点 LUN1) /u01 (第二个挂载点LUN2) /disk01 目录 : /u01/app/oracle /u01/app/app 文件 : 控制文件 :c ...
- Python开发入门与实战3-Django动态页面
3.Django动态页面 上一章节我们实现的helloworld视图是用来演示Django网页是创建的,它不是一个动态网页,每次运行/helloworld/,我们都将看到相同的内容,它类似一个静态HT ...
- 应用容器Application container
应用容器是最基本的组件,用于布局的容器. 属性 样式 事件 默认白边各24像素,默认为浏览器大小可以设置整体背景 边距等. 根应用文件就是第一个加载的文件.
- poj2253
此题略坑,%.3lf用g++一直WA,c++过的 //Accepted 468 KB 16 ms #include <cstdio> #include <cstring> #i ...