在Android应用中加入自己的手势处理

1745阅读 0评论2012-02-21 无色T恤
分类:

作者:温尚书,讲师。

Tag:海豚浏览器 dolphin browser 手势 手势操作 手势输入 Gesture GestureLibrary

海豚浏览器是由国人推出的一款移动浏览器,自2010年推出后,即逐渐在国外引起较大的反响。它提供了人性化、流畅的用户体验。其中有一个用户手势控制功能,更是引起了大家很大的关注。

下面我们先来看看海豚浏览器的这个功能,如下图所示,如果我们在其中用手指输入一个“S”,它将会打开预先定义好的和这个手势相对应的网址。

那么,如何实现它的手势功能呢?下面我们一步步来实现这个功能。

首先,我们需要先定义一个“手势-字符串”对应的手势库(GestureLibrary),我们可以用Android AVD中自带的一个工具来实现自定义手势库的功能。如下图左所示,在AVD(即手机模拟器)中打开Gesture Builder这个应用,即可在这里定义手势和其对应的名称(字符串),如下图中所示。下图右是自己定义好的手势和它的对应的名称列表。

这里定义的手势库会将其保存到一个文件中,默认情况下保存在/mnt/sdcard/gestures这个文件中,可以将这个文件从AVD对应的文件系统下倒出来,然后,放入要用到手势处理的项目中,一般把它放到/res/raw这个目录下。

当定义好并且将手势库放到项目中后,我们就可以使用这些手势了。使用手势的基本思路是,提供一个视图(View),让用户可以在此用手指在屏幕上画出手势,然后,根据用户画出的手势,和我们签名定义的手势库里的手势进行匹配,如果能找到相匹配的手势,则根据这个手势找到其对应的名称,然后根据这个名称,来进行不同的处理。

和手势处理相关的几个类如下:

●    GestureLibrary:用于表示单个的手势库;
        ●    GestureLibraries:用于表示所有的手势库,可以通过它来得到单个的GestureLibrary;
        ●    Gesture:表示一个手势;
        ●    Prediction:它封装了和手势相关的两个属性:对应手势的名称(name),以及用户画出的手势图形和手势库中相匹配的手势图形之间的相似程度(score);
        ●    OnGesturePerformedListener:用于监听用户在屏幕上的手势操作的一个监听接口。
        ●    GestureOverlayView:用于接收用户的手势操作的一个视图(View),它位于android.gesture包下面,而不是android.widget包下面。

下面我们自己来实现一个自定义手势功能。

首先,我们要在需要用到手势的界面中,加入GestureOverlayView这个视图。正如它的名字所展示的一样,它可以覆盖在其他视图上面,不进行手势操作的时候,对用户并不会构成干扰。

下面是对应的Layout中的设置:

                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_alignParentBottom="true"
                android:layout_below="@id/divider" >

        

                xmlns:android=""
                        android:id="@+id/gestures1"
                        android:layout_width="fill_parent"
                        android:layout_height="fill_parent"
                        android:layout_weight="1"
                        android:eventsInterceptionEnabled="true"
                        android:gestureStrokeLengthThreshold="12"
                        android:gestureStrokeType="multiple"
                        >

                                                android:id="@+id/listView1"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content" >
                        
                
        

这样,我们就在ListView上添加了一个手势输入视图GestureOverlayView了,以为它不在android.widget包中,所以这里需要写上全路径。对于GestureOverlayView的一些属性,说明如下:

1)gestureStrokeType:设置画笔(Stroke)的类型。大多数情况下,gestures都是通过一笔完成。然而有一些特别的需求就需要通过多个笔画来实现,例如通过“+”来实现“添加”的行为,则可以将其值设置成“multiple”,如果是单一笔画,则可以将其值设置成“single”。

2)eventsInterceptionEnabled: 可以简单理解为当前应用程序在Gesture overlay模式下屏蔽其它Views Events的开关。当它设置为true时,所有基于当前应用程序屏幕的操作都被视作为绘制gestures的行为,从而避免用户与应用程序界面的交互造成混乱。

3)orientation:这个属性作为当前Gesture recognizing的参考标准(相当于filter的作用),例如:在这个例子中的Items垂直排列,所有基于Overlay的垂直 (vertical) gesture,都无法被识别为有效的gesture,其与当前的垂直滚动条操作造成混淆。对于水平 (horizontal) gesture可以立即识别为有效的gesture,或者任何以垂直为起始的操作需要至少包含一段水平的绘制轨迹才可以被正常识别。

4)gestureColor:画笔的颜色,可以设置成“#rgb”、“#rrggbb”、“#argb”或者“#aarrggbb”各种格式中的一种。

在Layout中设置好用于接收手势收入的GestureOverlayView以后,就可以在程序中对用户的手势操作进行处理了。

首先,我们要将我们预先定义的手势库装入进来,如下:

GestureLibrary        gesLib         = GestureLibraries.fromRawResource(this, R.raw.gestures);
        gesLib.load();

然后,在GestureOverlayView上加上手势处理监听器:

gestureoverlay1
                        .addOnGesturePerformedListener(new MyOnGesturePerformedListener());

在MyOnGesturePerformedListener中,实现其onGesturePerformed回调方法,它有2个参数: 第一个参数GestureOverlayView,此处指的是触发Gesture事件的GestureOverlayView对象,第二个参数Gesture,封装的是用户输入的手势操作。我们得到这个Gesture对象后,即可使用它跟我们预先定义的手势库中的手势进行匹配,它将会返回一个ArrayList类型的Prediction列表,将所有和它匹配的手势信息都放到里面,且其匹配程度从高到低排列:

ArrayList predictions = gesLib
                                                        .recognize(gesture);

然后,我们既可以根据Prediction中的名称(name)和相似程度(score)来对用户输入的手势做出响应。

if (predictions.size() > 0) {
        //只要取出最相似的那个手势即可
                rediction prediction = predictions.get(0);
                if (prediction.name.equals("add") // 手势名称是“add”
                                && prediction.score > 3.0) {// 用户手势和定义好的手势库中的手势相似程度
                                                //do something
                }
        }

嵌入式及3G相关资源及学习请点击:            
上一篇:Linux环境下段错误的产生原因及调试方法小结
下一篇:awk自定义函数的使用