Android移动开发-添加手势以及识别用户手势
2017-09-20 10:15
357 查看
所谓手势,其实是指用户手指或触摸笔在触摸屏上的连续触碰的行为,比如在屏幕上从左向右划出的一个动作,就是手势;再比如在屏幕上画出一个圆圈也是手势。手势这种连续的触碰会形成某个方向上的移动趋势,也会形成一个不规则的几何图形。Android对两种手势行为都是提供了支持。
- 对于第一种手势行为,Android提供了手势检测,并为手势检测提供了相应的监听器;
- 对于第二种手势行为,Android允许开发者添加手势,并提供了相应的API识别用户手势。
下面的应用程序在界面布局中使用了GestureOverlayView。
布局文件layout/activity_main.xml代码:
由于GestureOverlayView并不是标准的视图组件,因此在界面布局中使用该组件时需要使用全限类名。
上面的程序使用GestureOverlayView组件时指定了一个android:gestureStrokeType参数,该参数控制手势是否需要多一笔完成。大部分时候,一个手势只要一笔就可以完成,此时可将该参数设为single。如果该手势需要多笔来完成,则将该参数设为multiple。
接下来程序将会为GestureOverlayView添加一个OnGesturePerformedListener监听器,当手势事件完成时,该监听器会打开一个对话框,让用户选择保存该手势。
MainActivity.java逻辑代码:
上面程序中标为序号①的代码为GestureOverlayView绑定OnGesturePerformedListener监听器,该监听器用于在手势完成时提供响应——它的响应就是打开一个对话框。该对话框的界面布局代码如下。
layout/save.xml
AddGesture程序中的标为②序号的代码是在对话框中完成的,这段代码用于从SD卡的指定文件中加载手势库,并添加用户刚刚输入的手势。
注意:上面的程序需要将手势库保存在SD卡上,因此还需要在清单文件AndroidManifest.xml里面添加程序的读写SD卡的权限。
在清单文件AndroidManifest.xml里添加的权限代码如下:
recognize(Gesture ges)方法的返回值为ArrayList< Predicttion>,其中Prediction封装了手势的匹配信息,Prediction对象的name属性代表了匹配的手势名,score属性代表了手势的相似度。
下面的程序将会利用前一个程序所创建的手势库来识别手势。该程序的界面很简单,只是在界面中定义了一个GestureOverlayView组件,允许用户在该组件上输入手势。程序为该组件绑定了OnGesturePerformedListener监听器,该监听器检测到用户手势完成时,就会调用手势库来识别用户输入的手势。
layout/activity_main.xml界面代码:
layout/result.xml界面代码:
MainActivity.java逻辑代码:
注意:上面的程序同样需要将手势库保存在SD卡上,因此还需要在清单文件AndroidManifest.xml里面添加程序的读写SD卡的权限。
在清单文件AndroidManifest.xml里添加的权限代码如下:
上面的MainActivity.java程序中的标序号为①的代码就负责调用前一个程序的手势库来识别用户刚输入的手势,用户只要在屏幕上绘制一个大致与之前相似的手势,即可提示的结果。
- 对于第一种手势行为,Android提供了手势检测,并为手势检测提供了相应的监听器;
- 对于第二种手势行为,Android允许开发者添加手势,并提供了相应的API识别用户手势。
添加手势
Android除了提供手势检测之外,还允许应用程序把用户手势(多个持续的触摸事件在屏幕上形成特定的形状)添加到指定文件中,已备以后使用——如果程序需要,当用户下次再次画出该手势时,系统将可识别该手势。下面的应用程序在界面布局中使用了GestureOverlayView。
布局文件layout/activity_main.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:gravity="center_horizontal" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="请在下面屏幕上绘制手势" /> <!-- 使用手势绘制组件 --> <android.gesture.GestureOverlayView android:id="@+id/gesture" android:layout_width="match_parent" android:layout_height="match_parent" android:gestureStrokeType="multiple" /> < 4000 ;/LinearLayout>
由于GestureOverlayView并不是标准的视图组件,因此在界面布局中使用该组件时需要使用全限类名。
上面的程序使用GestureOverlayView组件时指定了一个android:gestureStrokeType参数,该参数控制手势是否需要多一笔完成。大部分时候,一个手势只要一笔就可以完成,此时可将该参数设为single。如果该手势需要多笔来完成,则将该参数设为multiple。
接下来程序将会为GestureOverlayView添加一个OnGesturePerformedListener监听器,当手势事件完成时,该监听器会打开一个对话框,让用户选择保存该手势。
MainActivity.java逻辑代码:
package com.fukaimei.addgesture; import android.content.DialogInterface; import android.gesture.Gesture; import android.gesture.GestureLibraries; import android.gesture.GestureLibrary; import android.gesture.GestureOverlayView; import android.graphics.Bitmap; import android.graphics.Color; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.widget.ImageView; public class MainActivity extends AppCompatActivity { EditText editText; GestureOverlayView gestureView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 获取文本编辑框 editText = (EditText) findViewById(R.id.gesture_name); // 获取手势编辑视图 gestureView = (GestureOverlayView) findViewById(R.id.gesture); // 设置手势的绘制颜色 gestureView.setGestureColor(Color.RED); // 设置手势的绘制宽度 gestureView.setGestureStrokeWidth(4); // 为gesture的手势完成事件监听器 gestureView.addOnGesturePerformedListener(new GestureOverlayView.OnGesturePerformedListener() { //① @Override public void onGesturePerformed(GestureOverlayView overlay, final Gesture gesture) { // 加载sava.xml界面布局代表的视图 View saveDialog = getLayoutInflater().inflate(R.layout.save, null); // 获取saveDialog里的show组件 ImageView imageView = (ImageView) saveDialog.findViewById(R.id.show); // 获取saveDialog里的gesture_name组件 final EditText gestureName = (EditText) saveDialog.findViewById(R.id.gesture_name); // 根据Gesture包含的手势创建一个位图 Bitmap bitmap = gesture.toBitmap(128, 128, 10, 0xffff0000); imageView.setImageBitmap(bitmap); // 使用对话框显示saveDialog组件 new AlertDialog.Builder(MainActivity.this).setView(saveDialog).setPositiveButton("保存", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // 获取指定文件对应的手势库 GestureLibrary gestureLib = GestureLibraries.fromFile("/mnt/sdcard/mygestures"); //② // 添加手势 gestureLib.addGesture(gestureName.getText().toString(), gesture); //② // 保存手势库 gestureLib.save(); //② } }).setNegativeButton("取消", null).show(); } }); } }
上面程序中标为序号①的代码为GestureOverlayView绑定OnGesturePerformedListener监听器,该监听器用于在手势完成时提供响应——它的响应就是打开一个对话框。该对话框的界面布局代码如下。
layout/save.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: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:layout_marginRight="8dip" android:text="请填手势名" /> <!-- 定义一个文本框来让用户输入手势名 --> <EditText android:id="@+id/gesture_name" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> <!-- 定义一个图片框来显示手势 --> <ImageView android:id="@+id/show" android:layout_width="128dp" android:layout_height="128dp" android:layout_marginTop="10dp" /> </LinearLayout>
AddGesture程序中的标为②序号的代码是在对话框中完成的,这段代码用于从SD卡的指定文件中加载手势库,并添加用户刚刚输入的手势。
注意:上面的程序需要将手势库保存在SD卡上,因此还需要在清单文件AndroidManifest.xml里面添加程序的读写SD卡的权限。
在清单文件AndroidManifest.xml里添加的权限代码如下:
<!-- 在SD卡中创建与删除文件权限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <!-- 向SD卡写入数据权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
识别用户手势
前面已经提到,GestureLibrary提供了recognize(Gesture ges)方法来识别手势,该方法将会返回该手势库中所有与ges匹配的手势——两个手势的图形越相似,相似度越高。recognize(Gesture ges)方法的返回值为ArrayList< Predicttion>,其中Prediction封装了手势的匹配信息,Prediction对象的name属性代表了匹配的手势名,score属性代表了手势的相似度。
下面的程序将会利用前一个程序所创建的手势库来识别手势。该程序的界面很简单,只是在界面中定义了一个GestureOverlayView组件,允许用户在该组件上输入手势。程序为该组件绑定了OnGesturePerformedListener监听器,该监听器检测到用户手势完成时,就会调用手势库来识别用户输入的手势。
layout/activity_main.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:orientation="vertical"> <!-- 使用手势编辑组件 --> <android.gesture.GestureOverlayView android:id="@+id/gesture" android:layout_width="match_parent" android:layout_height="match_parent" android:gestureStrokeType="multiple" /> </LinearLayout>
layout/result.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:orientation="vertical"> <ListView android:id="@+id/show" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
MainActivity.java逻辑代码:
package com.fukaimei.recognisegesture; import android.gesture.Gesture; import android.gesture.GestureLibraries; import android.gesture.GestureLibrary; import android.gesture.GestureOverlayView; import android.gesture.Prediction; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.Toast; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { // 定义手势编辑组件 GestureOverlayView gestureView; // 记录手机上已有的手势库 GestureLibrary gestureLibrary; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 读取上一个程序所创建的手势库 gestureLibrary = GestureLibraries.fromFile("/mnt/sdcard/mygestures"); if (gestureLibrary.load()) { Toast.makeText(this, "手势文件装载成功", Toast.LENGTH_SHORT).show(); } else { a5d5 Toast.makeText(this, "手势文件装载失败", Toast.LENGTH_SHORT).show(); } // 获取手势编辑组件 gestureView = (GestureOverlayView) findViewById(R.id.gesture); // 为手势编辑组价绑定事件监听器 gestureView.addOnGesturePerformedListener(new GestureOverlayView.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<Object> adapter = new ArrayAdapter<Object>(MainActivity.this, android.R.layout.simple_dropdown_item_1line, result.toArray()); // 使用一个带List的对话框来显示所有匹配的手势 new AlertDialog.Builder(MainActivity.this).setAdapter(adapter, null) .setPositiveButton("确定", null).show(); } else { Toast.makeText(MainActivity.this, "无法找到能匹配的手势", Toast.LENGTH_SHORT).show(); } } }); } }
注意:上面的程序同样需要将手势库保存在SD卡上,因此还需要在清单文件AndroidManifest.xml里面添加程序的读写SD卡的权限。
在清单文件AndroidManifest.xml里添加的权限代码如下:
<!-- 在SD卡中创建与删除文件权限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <!-- 向SD卡写入数据权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
上面的MainActivity.java程序中的标序号为①的代码就负责调用前一个程序的手势库来识别用户刚输入的手势,用户只要在屏幕上绘制一个大致与之前相似的手势,即可提示的结果。
相关文章推荐
- Android增加、识别用户手势
- Android OnGestureListener用法 识别用户手势 左右滑动
- android可以识别用户的手势
- Android OnGestureListener用法 识别用户手势 左右滑动
- android之手势添加&识别
- Android OnGestureListener用法 识别用户手势 左右滑动
- Android中添加和识别手势操作
- Android开发——用户在屏幕上的手势识别
- Android OnGestureListener用法 识别用户手势 上下左右滑动
- android添加新的资源文件夹无法识别以及读取外置SD卡解决方案
- Android开发——用户在屏幕上的手势识别
- Android中实现Launcher功能之二 ----- 添加窗口小部件以及AppWidget的创建详解
- 动态添加fragment与手势切换(一)(android)
- Android 手势识别—缩放
- Android手势识别GestureOverlayView手势自动消除和多笔画识别问题
- Android入门(54)——第九章 使用GestureOverlayView进行手势识别
- (转)【Android游戏开发十六】Android Gesture之【触摸屏手势识别】操作!利用触摸屏手势实现一个简单切换图片的功能!
- 【原创】Ubuntu下更改root用户密码以及添加/删除用户
- Android OnTouchListener 触摸事件 & GestureDetector 手势识别类