手势创建主要用到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>