Android除了提供手势检测之外,还允许把用户手势添加到指定文件中,以备以后使用,当用户再次画出该手势时,系统可识别该手势。Android使用GestureLibrary代表手势库,提供GestureLibraries工具类来创建手势库。GestureLibraries提供如下4个静态方法从不同位置加载手势库:
一旦程序中获得了GestureLibrary对象后,就可以用如下方法来添加、识别手势:
另外Android还提供了一个手势编辑组件:GestureOverlayView,用户可以在上面绘制手势。然后对它绑定事件监听器,响应手势事件开始、结束、完成、取消等事件。下面通过一个简单实例来演示手势的添加以及识别自定义手势,代码如下:
AddGestureActiv:
package com.lovo.activity; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; 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.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import com.lovo.addgesture.R; public class AddGestureActivity extends Activity { private GestureOverlayView gestureView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 获取手势编辑视图 gestureView = (GestureOverlayView) findViewById(R.id.main_gesture); // 设置手势绘制的颜色 gestureView.setGestureColor(Color.RED); // 设置手势的绘制宽度 gestureView.setGestureStrokeWidth(4); // 为 gesture的手势完成事件绑定事件监听器 gestureView.addOnGesturePerformedListener(new OnGesturePerformedListener() { @Override public void onGesturePerformed(GestureOverlayView overlay, final Gesture gesture) { // 加载save.xml界面布局代表的视图 View saveDialog = getLayoutInflater().inflate(R.layout.save, null); // 获取saveDialog里的show组件 ImageView imageView = (ImageView) saveDialog.findViewById(R.id.save_iv_show); // 获取saveDialog里的gesture_name组件 final EditText gestureName = (EditText) saveDialog .findViewById(R.id.save_et_gesture_name); // 根据Gesture包含的手势创建一个位图 Bitmap bitmap = gesture.toBitmap(128, 128, 10,0xFFFF0000); imageView.setImageBitmap(bitmap); // 使用对话框显示saveDialog组件 new AlertDialog.Builder(AddGestureActivity.this) .setView(saveDialog) .setPositiveButton("保存", new android.content.DialogInterface.OnClickListener() { @Override public void onClick( DialogInterface dialog,int which) { // 获取指定文件对应的手势库 GestureLibrary gestureLib = GestureLibraries .fromFile(AddGestureActivity.this .getFilesDir()+ "/gestures"); // 添加手势 gestureLib.addGesture(gestureName.getText().toString(),gesture); // 保存手势库 boolean isSave = gestureLib.save(); String result = isSave ? "保存成功": "保存失败"; Log.i("isSave", result); } }).setNegativeButton("取消", null).show(); } }); Button turnBtn = (Button) findViewById(R.id.main_btn_turn); turnBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(AddGestureActivity.this, RecogniseGestureActivity.class); startActivity(intent); } }); } }
Add布局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:layout_gravity="center_horizontal" 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:text="请在下面屏幕上绘制手势" /> <Button android:id="@+id/main_btn_turn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:text="跳转到手势识别界面" /> </LinearLayout> <!-- 使用手势绘制组件 --> <android.gesture.GestureOverlayView android:id="@+id/main_gesture" android:layout_width="match_parent" android:layout_height="match_parent" android:gestureStrokeType="multiple" /> </LinearLayout>
识别手势的Activity:
package com.lovo.activity; import java.util.ArrayList; 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.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.Toast; import com.lovo.addgesture.R; public class RecogniseGestureActivity extends Activity { // 定义手势编辑组件 private GestureOverlayView gestureView; // 记录手机上已有的手势库 GestureLibrary gestureLibrary; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.recognise); // 读取上一个程序所创建的手势库 gestureLibrary = GestureLibraries.fromFile(this.getFilesDir() + "/gestures"); if (gestureLibrary.load()) { Toast.makeText(this, "手势文件装载成功!", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "手势文件装载失败!", Toast.LENGTH_SHORT).show(); } // 获取手势编辑组件 gestureView = (GestureOverlayView) findViewById(R.id.recognise_gesture); // 为手势编辑组件绑定事件监听器 gestureView .addOnGesturePerformedListener(new OnGesturePerformedListener() { @Override public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { // 识别用户刚刚所绘制的手势 ArrayList<Prediction> predictions = gestureLibrary .recognize(gesture); ArrayList<String> result = new ArrayList<String>(); // 遍历所有找到的Prediction对象 for (Prediction pred : predictions) { // 只有相似度大于2.0的手势才会被输出 if (pred.score > 2.0) { result.add("与手势【" + pred.name + "】的相似度为" + pred.score); } } if (result.size() > 0) { ArrayAdapter adapter = new ArrayAdapter( RecogniseGestureActivity.this, android.R.layout.simple_dropdown_item_1line, result.toArray()); // 使用一个带List的对话框来显示所有匹配的手势 new AlertDialog.Builder( RecogniseGestureActivity.this) .setAdapter(adapter, null) .setPositiveButton("保存", null).show(); } else { Toast.makeText(RecogniseGestureActivity.this, "无法找到匹配的手势!", Toast.LENGTH_SHORT).show(); } } }); Button turnBtn = (Button) findViewById(R.id.recognise_btn_turn); turnBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { finish(); } }); } }
识别手势的布局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:layout_gravity="center_horizontal" 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:text="请在下面屏幕上绘制手势" /> <Button android:id="@+id/recognise_btn_turn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:text="返回到增加手势界面" /> </LinearLayout> <!-- 使用手势绘制组件 --> <android.gesture.GestureOverlayView android:id="@+id/recognise_gesture" android:layout_width="match_parent" android:layout_height="match_parent" android:gestureStrokeType="multiple" /> </LinearLayout>