源碼:http://files.cnblogs.com/android100/gesture.builder.zip
使用一些瀏覽器或者輸入法應用時會有一些手勢操作,還可以自定義手勢。這些神奇的操作是怎么做的呢?這一篇重點記錄手勢的識別和創建。這篇的內容使用到的是android.gesture包,具體的例子參考的是Sample中GestureBuilder程序。
1、手勢創建
手勢創建主要用到GestureOverlayView和GestureLibrary。GestureOverlayView的父類為android.widget.FrameLayout,是手勢繪圖區。GestureLibrary類主要對手勢進行保存、刪除等操作的,存放手勢的倉庫。下面給出創建手勢的例子,如下圖,可以定義如圖手勢打開csdn.net
1.1、創建繪圖區
- GestureOverlayView overlay = (GestureOverlayView) findViewById(R.id.gestures_overlay);
- overlay.setGestureStrokeType(GestureOverlayView.GESTURE_STROKE_TYPE_MULTIPLE);
- overlay.setFadeOffset(2000); //多筆畫每兩次的間隔時間
- overlay.setGestureColor(Color.CYAN);//畫筆顏色
- overlay.setGestureStrokeWidth(6);//畫筆粗細值
- overlay.addOnGestureListener(new GesturesProcessor());
1.2、監聽繪制
- private class GesturesProcessor implements GestureOverlayView.OnGestureListener {
- public void onGestureStarted(GestureOverlayView overlay, MotionEvent event) {
- mDoneButton.setEnabled(false);
- mGesture = null;
- }
- public void onGesture(GestureOverlayView overlay, MotionEvent event) {
- }
- public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) {
- mGesture = overlay.getGesture();
- if (mGesture.getLength() < LENGTH_THRESHOLD) {
- overlay.clear(false);
- }
- mDoneButton.setEnabled(true);
- }
- public void onGestureCancelled(GestureOverlayView overlay, MotionEvent event) {
- }
- }
1.3、保存手勢
- public void addGesture(View v) {
- if (mGesture != null) {
- final TextView input = (TextView) findViewById(R.id.gesture_name);
- final CharSequence name = input.getText();
- if (name.length() == 0) {
- input.setError(getString(R.string.error_missing_name));
- return;
- }
- /**
- * 獲取手勢庫
- * private final File mStoreFile = new File(Environment.getExternalStorageDirectory(), "gestures");
- * GestureLibrary sStore = GestureLibraries.fromFile(mStoreFile);
- *
- */
- final GestureLibrary store = GestureBuilderActivity.getStore();
- store.addGesture(name.toString(), mGesture);
- store.save();
- setResult(RESULT_OK);
- final String path = new File(Environment.getExternalStorageDirectory(),
- "gestures").getAbsolutePath();
- Toast.makeText(this, getString(R.string.save_success, path), Toast.LENGTH_LONG).show();
- } else {
- setResult(RESULT_CANCELED);
- }
- finish();
- }
2、手勢識別
手勢識別也是經過創建繪圖區、監聽繪制、比對結果三個過程,這里直接給出代碼。
- public class GesturePerformedActivity extends Activity {
- private final File mStoreFile = new File(
- Environment.getExternalStorageDirectory(), "gestures");
- // 手勢庫
- GestureLibrary mGestureLib;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- setContentView(R.layout.gesture_perform);
- // 手勢畫板
- GestureOverlayView gestures = (GestureOverlayView) findViewById(R.id.gestures_overlay);
- gestures.setGestureStrokeType(GestureOverlayView.GESTURE_STROKE_TYPE_MULTIPLE);
- gestures.setFadeOffset(2000); // 多筆畫每兩次的間隔時間
- gestures.setGestureColor(Color.CYAN);// 畫筆顏色
- gestures.setGestureStrokeWidth(6);// 畫筆粗細值
- // 手勢識別的監聽器
- gestures.addOnGesturePerformedListener(new GestureOverlayView.OnGesturePerformedListener() {
- @Override
- public void onGesturePerformed(GestureOverlayView overlay,
- Gesture gesture) {
- // 從手勢庫中查詢匹配的內容,匹配的結果可能包括多個相似的結果,匹配度高的結果放在最前面
- ArrayList<Prediction> predictions = mGestureLib
- .recognize(gesture);
- if (predictions.size() > 0) {
- Prediction prediction = (Prediction) predictions.get(0);
- // 匹配的手勢
- if (prediction.score > 1.0) { // 越匹配score的值越大,最大為10
- Toast.makeText(GesturePerformedActivity.this,
- prediction.name, Toast.LENGTH_SHORT).show();
- }
- }
- }
- });
- if (mGestureLib == null) {
- mGestureLib = GestureLibraries.fromFile(mStoreFile);
- mGestureLib.load();
- }
- }
- }


最后還有點問題,就是多筆畫識別問題,這里沒有很好的解決,使用OnGesturePerformedListener接聽結束,有的多筆畫會識別失敗,尤其簡單的橫線豎線組合,復雜的卻沒有問題。如果使用GestureOverlayView.OnGestureListener監聽結束,每一筆畫都會調用,不能處理未知筆畫數的識別。如果哪位同學完美解決了多筆畫問題,請多指教,謝謝。