Pro Android学习笔记(一四六):触摸屏(5):自定义手势

文章转载只能用于非商业性质,且不能带有虚拟货币、积分、注册等附加条件。转载须注明出处http://blog.csdn.net/flowingflying/以及作者@恺风Wei。

Gestures Builder

我们可以自定义手势。在Android模拟器上提供一个Gestures Builder,帮助我们自定义手势。

Pro Android学习笔记(一四六):触摸屏(5):自定义手势_第1张图片

通过Gestures Builder可以自定义手势,并保持在/storage/sdcard/gestures文件中,这是个二进制文件,我们将其pull出来,将之放在我们需要使用自定义手势小例子的/res/raw中。

可以定义多个同一名字的手势。目前手势不支持多点触摸,但是可以支持多笔划,也就是多gesture stroke,每笔之间要快,间隔时间不能超过420ms,否则应用会认为是下一个手势,删除之前的笔画。可以在Gestures Builder的源代码中修改这个缺省的值,在/res/layout/create_gesture.xml中增加属性android:fadeOffset="1000",则更改为1秒。

自定义手势

我们通过了Gestures Builder定义了三个手势,其中smark有两个形态。下面,我们将在activity中识别这些自定义的手势。

layout的xml文件如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout … …>
    <TextView android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="给出手势,我们将尝试分析" />
     
    <!-- 1、如果要支持多笔画,则必须设置android:gestureStrokeType="multiple",也可以在code里面通过setGestureStrokeType(int)进行设置
         2、android:fadeOffset缺省为420,表示stroke之间的最大间隔时间为420ms,如果我们使用模拟器,可以将此数值增大,本例子设置为1s。
         3、可以设置stroke的颜色android:gestureColor和粗细android:gestureStrokeWidth -->

    <android.gesture.GestureOverlayView android:id="@+id/my_gesture_overlay"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gestureStrokeType="multiple"
        android:fadeOffset="1000"
/>   
</LinearLayout>

代码如下

public class MyGestureActivity extends Activity implements OnGesturePerformedListener{
    private GestureLibrary gestureLib = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_gesture_activity);

       
        //【1】获取自定义gesture lib文件。我们将Gestures Builder生成的二进制文件放入/res/raw,这样可以作为apk的一部分。
        gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures);
               
        // 也可以放在SD卡上,作为文件读取。如果要允许用户重新定义自己的手势,采用文件的方式,覆盖原来的手势文件,也可以在创建新的自定义手势lib文件,存放在SD卡中,load入两个手势lib,在识别的时候,先与用户的手势lib进行识别,在于我们定义的手势lib进行识别。要写手势lib,可以参考Gestures Builder的source code(我在android的sample中没有发现GesturesBuilder,可以在https://github.com/android/platform_development/tree/master/apps/GestureBuilder中下载,也可以用intent的方式调用Gestures Builder。 
        // String fileName = Environment.getExternalStorageDirectory().toString()+"/gesture";
        // gestureLib = GestureLibraries.fromFile(fileName);
         
        
        //在load()之前,可以对gestureLib的一些参数进行设置
        //gestureLib.setOrientationStyle(GestureStore.ORIENTATION_INVARIANT);//表示在屏幕旋转中有更好的识别 
        //gestureLib.setSequenceType(GestureStore.SEQUENCE_INVARIANT);
//表示在多strokes的情况下,可以不按笔画顺序
       
       //【2】导入自定义gesture lib。
        if(!gestureLib.load()){
            Toast.makeText(this, "无法load入自定义手势!", Toast.LENGTH_LONG).show();
            finish();
        }
       
        //【2.1】我们查看自定义手势的信息。
        showMyGestureLibInfo();
        //【2.2】添加手势监听器
        GestureOverlayView gestureView = (GestureOverlayView)findViewById(R.id.my_gesture_overlay);
        gestureView.addOnGesturePerformedListener(this);
    }   
    
    @Override  //【3】如果Android识别出手势,将触发此回调函数 
    public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture)

        //与自定义的手势库进行对比 
        ArrayList<Prediction> predictions = gestureLib.recognize(gesture);
        //每个自定义手势都有一个匹配分数,分值越高,匹配度越高,已经按分值从高到低进行排序。小例子简单将分值打印出来。
        if(predictions.size() > 0){
            Prediction prediction = (Prediction) predictions.get(0); 
            if(prediction.score > 1.0){
                Toast.makeText(this, prediction.name, Toast.LENGTH_LONG).show();
                for(int i = 0 ; i < predictions.size(); i ++){
                    Prediction p =     (Prediction) predictions.get(i);
                    Log.v("MyGesture"," ["+ i +"] " + p.name + " score=" + p.score);
                }
            }
        }
    }

    //【2.1】我们查看自定义手势的信息。
    private void showMyGestureLibInfo(){
        Log.v("MyGesture","Gesture Lib feature :");
        Log.v("MyGesture","Orientation Style : " + gestureLib.getOrientationStyle());
        Log.v("MyGesture","Sequence Type : " + gestureLib.getSequenceType());
        for(String gestureName : gestureLib.getGestureEntries()){
            Log.v("MyGesture","-------------");
            Log.v("MyGesture","Gesture [" + gestureName +"]");
            for(Gesture gesture: gestureLib.getGestures(gestureName)){               
                Log.v("MyGesture","  ID = " + gesture.getID());
                Log.v("MyGesture","    Strokes count = " + gesture.getStrokesCount());
                Log.v("MyGesture","    Length = " + gesture.getLength());
            }
        }
    }

}

小例子的运行截图如下:

Pro Android学习笔记(一四六):触摸屏(5):自定义手势_第2张图片Pro Android学习笔记(一四六):触摸屏(5):自定义手势_第3张图片

相关小例子代码:Pro Android学习:touch screen小例子

相关链接:我的Android开发相关文章

你可能感兴趣的:(Pro Android学习笔记(一四六):触摸屏(5):自定义手势)