手势输入

在触摸屏世界中,使用复杂的手势(如在屏幕上不同方向多点触摸)是使交互简单有趣的非常好的方式。从Android 1.6(API level 4)开始提供手势API。在该API中,最简单的方式是使用android.gesture.GestureOverlayView给应用添加手势输入功能:


<!-- an example usage of GestureOverlayView in a layout xml -->
<android.gesture.GestureOverlayView
        xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/gestures"
    android:layout_
    android:layout_
    android:gestureStrokeType="multiple"
    android:eventsInterceptionEnabled="true">
</<android.gesture.GestureOverlayView>
  

GestureOverlayView是一个专门的FrameLayout,你可以在该视图上放置其他widget,或者包含其他widget。它可以捕捉触摸屏的笔画并使用有颜色的线条(默认是黄色)来显示笔画。GestureOverlayView.OnGesturePerformedListener接口用来支持对手势做出响应:


GestureOverlayView gestures = (GestureOverlayView) findViewById(R.id.gestures);
gestures.addOnGesturePerformedListener(
                            new GestureOverlayView.OnGesturePerformedListener {
    @Override
    public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
        // do nothing for now
    }
});
  

一旦给出某个手势,则可以查看Gesture库看能否识别该手势。Gesture库可以使用GestureLibraries类的静态方法,通过各种方式读取。加载Gesture库(加载GestureStore)之后,可以给其传递手势,并使用recognize方法分析它。该方法会返回Predictions列表,每个Prediction包含一个打分和名称,打分表示和库内该名称的手势的接近程度:


final GestureLibrary library = GestureLibraries.fromFile("/Some/File/Path");
library.load;         // load library
GestureOverlayView gestures = (GestureOverlayView) findViewById(R.id.gestures);
gestures.addOnGesturePerformedListener(
                            new GestureOverlayView.OnGesturePerformedListener {
    @Override
    public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
            // do the recognize
        ArrayList<Prediction> predictions = library.recognize(gesture);
        if (predictions.size > 0) {
            for(Prediction prediction: predictions) {
                // the score is high enough that we know it's a hit
                if (prediction.score > 1.0) {
                    // let's show a toast telling us what the gesture is named
                    Toast.makeText(this,
                      prediction.name, Toast.LENGTH_SHORT).show;
                }
            }
        }
    }
});
  

Gesture类的基础结构中包含多个GestureStroke对象,每个GestureStroke对象由一组GesturePoint对象组成。GesturePoint由(x,y)坐标以及生成该坐标点的时间戳组成。当在GestureStore(在GestureLibrary库内)中保存Gesture时,把名称(string)作为密钥。

在GestureLibrary中增加一个Gesture是非常简单的。提供和该手势关联的名称和Gesture对象,然后把它保存到GestureLibrary中。注意,库必须是从外部文件源中读取的(如SD卡或私有文件),这样库才是可修改并可存储的。从原始资源中读取的库是只读的(使用GestureLibraries.fromRawResource(context,resId)):


public void saveGesture(String name, Gesture gesture) {
    library.addGesture(name, gesture);
    library.save;
}
  

《Android程序设计:第2版》