手势创建主要用到GestureOverlayView和GestureLibrary。GestureOverlayView的父类,GestureLibrary类主要对手势进行保存、删除等操作的,存放手势的仓库。
工程目录:
1、首先先生成手势库,自己绘制喜欢的手势,然后命名好保存。详细代码如下
package com.example.gesture;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
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.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
public class drawActivity extends Activity {
private GestureOverlayView gestureView;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.drawgesture);
initUI();
}
private void initUI() {
// TODO Auto-generated method stub
gestureView = (GestureOverlayView) findViewById(R.id.gesture);
// 设置手势的绘制颜色
gestureView.setGestureColor(Color.RED);
// 设置手势的绘制宽度
gestureView.setGestureStrokeWidth(5);
// gestureView.setGestureColor(0xff009966);//设置画笔颜色
// gestureView.setFadeOffset(2000);//两个笔画之间的时间间隔
// 为gesture的手势完成事件绑定事件监听器
gestureView.addOnGesturePerformedListener(new OnGesturePerformedListener() {
@Override
public void onGesturePerformed(GestureOverlayView overlay,final Gesture gesture) {
// TODO Auto-generated method stub
AlertDialog.Builder builder = new AlertDialog.Builder(drawActivity.this);
LayoutInflater inflater = getLayoutInflater();
final View layout = inflater.inflate(R.layout.savegesture, null);
ImageView image = (ImageView)layout.findViewById(R.id.show);
// 根据Gesture包含的手势创建一个位图
Bitmap bitmap = gesture.toBitmap(128, 128, 10, 0xFFFF0000);
image.setImageBitmap(bitmap);
builder.setView(layout);
builder.setIcon(R.drawable.ic_launcher);
builder.setTitle(R.string.title);
builder.setPositiveButton("ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
EditText edit = (EditText)layout.findViewById(R.id.gesture_name);
// 获取指定文件对应的手势库
GestureLibrary gestureLib = GestureLibraries
.fromFile("/sdcard/gestures");
// 添加手势
gestureLib.addGesture(edit.getText().toString(),gesture);
// 保存手势库
gestureLib.save();
Toast.makeText(getApplicationContext(), "手势保存成功!", Toast.LENGTH_SHORT).show();
}
});
builder.setNeutralButton("cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
}
});
final AlertDialog dlg = builder.create();
dlg.show();
}
});
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
}
代码布局为:
<?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" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@string/ad"/>
<!-- 使用手势绘制组件 -->
<android.gesture.GestureOverlayView
android:id="@+id/gesture"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gestureStrokeType="multiple" />
</LinearLayout>
保存手势布局自定义dialog布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="8dip"
android:text="@string/gesture_name"
/>
<!-- 定义一个文本框来让用户输入手势名 -->
<EditText
android:id="@+id/gesture_name"
android:inputType="none"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
<!-- 定义一个图片框来显示手势 -->
<ImageView
android:id="@+id/show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp" />
</LinearLayout>
最后还需要添加权限:
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
2、生成的手势库保存路基可自己定义,gestures为手势库的名字
GestureLibrary gestureLib = GestureLibraries.fromFile("/sdcard/gestures");
3、手势的使用,在res目录下新建一个raw文件,然后添加手势库进来方便调用,首先是先获取手势库,然后对手势的相似度进行判断,可设置大小。最后对之前定义名手势名字进行判断,再执行自己想操作的。详细代码:
package com.example.gesture;
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.Prediction;
import android.gesture.GestureOverlayView.OnGesturePerformedListener;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
public class useActivity extends Activity {
GestureOverlayView gestureView;
GestureLibrary gLibrary;
boolean loadState;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.usegesture);
initUI();
}
private void initUI() {
// TODO Auto-generated method stub
gestureView = (GestureOverlayView) this.findViewById(R.id.myGesture);
gestureView.addOnGesturePerformedListener(new MyOnGesturePerformedListener());
// 创建手势库对象GestureLibrary
gLibrary = GestureLibraries.fromRawResource(this, R.raw.gestures);
// 加载手势库资源
loadState = gLibrary.load();
}
private final class MyOnGesturePerformedListener implements
OnGesturePerformedListener {
public void onGesturePerformed(GestureOverlayView overlay,
Gesture gesture) {
if (loadState) {//加载手势资源成功
// 获取画的图形进行匹配,匹配程度就是Prediction中的score
ArrayList<Prediction> predictions = gLibrary.recognize(gesture);
if (!predictions.isEmpty()) {// 如果用户画了图形,就会匹配
Prediction prediction = predictions.get(0);
Log.i("TAG", String.valueOf(prediction.score));
//prediction的score属性代表了与手势的相似程度
//prediction的name代表手势对应的字母
//这里要求匹配度要在30%以上
if (prediction.score > 3) {// 判断相似度大于3,与里面的两者进行匹配
if ("2".equals(prediction.name)) {//打电话
Toast.makeText(getApplicationContext(), "手势识别成功!", Toast.LENGTH_LONG).show();
Intent intent1 = new Intent(Intent.ACTION_CALL,
Uri.parse("tel:668301"));
startActivity(intent1);
}
} else {// 相似度小于1,不识别
Toast.makeText(getApplicationContext(), "手势识别率太低,请重新输入!", Toast.LENGTH_LONG).show();//手势识别率低,请重新输入
}
//判断识别度在百分之20以上
if(prediction.score >2){
if("3".equals(prediction.name)){
Toast.makeText(getApplicationContext(), "手势识别成功!", Toast.LENGTH_LONG).show();
//showToast(R.string.send);
Intent intent = new Intent(Intent.ACTION_CALL,Uri.parse("tel:668301"));
startActivity(intent);
}
}else {// 相似度小于1,不识别
Toast.makeText(getApplicationContext(), "手势识别率太低,请重新输入!", Toast.LENGTH_LONG).show();//手势识别率低,请重新输入
}
} else {//没有画图形
Toast.makeText(getApplicationContext(), "没有手势", Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(getApplicationContext(), "手势库没有加载成功", Toast.LENGTH_LONG).show();
}
}
}
}
实现的布局代码:
<?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" >
<TextView
android:layout_width="fill_parent"
android:gravity="center_horizontal"
android:textSize="20sp"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<android.gesture.GestureOverlayView
android:id="@+id/myGesture"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1.0"
/>
</LinearLayout>
完整的权限代码:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.gesture"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.gesture.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".drawActivity"></activity>
<activity android:name=".useActivity"></activity>
</application>
</manifest>