Android基础系列 - 手势自定义,识别手势
Posted SingleShu888
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android基础系列 - 手势自定义,识别手势相关的知识,希望对你有一定的参考价值。
之前把谷歌提供的android手势相关的官方文档和网上一些手势分析的文档,也写了一个简单的示例。
那么今天继续深入学习手势相关的API,增加手势提供了API,GestureLibrary和GestureOverlayView。
GestureLibrary中有几个常用的方法。
GestureLibraries .fromFile(Context con,String filepath); 获取GestureLibrary的主要途径。filepath是手势缓存的文件地址。
addGesture(String name,Gesture gesture);添加一个手势,name是该手势的名称。
save();调用保存的方法。
GestureOverlayView是手势相关API中直接与用户打交道的。它的一些常用方法。
setGestureStrokeType(GestureOverlayView.GESTURE_STROKE_TYPE_MULTIPLE);设置手势可多笔画绘制,默认情况为单笔画绘制 。
setGestureColor(Color.RED); 设置手势的颜色(红色) 。
setUncertainGestureColor(Color.RED);设置还没未能形成手势绘制是的颜色(红色) 。
setGestureStrokeWidth(10);设置手势宽度10。
setFadeOffset(500);手势绘制完成后淡出屏幕的时间间隔,即绘制完手指离开屏幕后相隔多长时间手势从屏幕上消失,可以理解为手势绘制完成手指离开屏幕后到调用onGesturePerformed的时间间隔,默认值为420毫秒,这里设置为0.5秒 。
addOnGesturePerformedListener(OnGesturePerformedListener listener);设置手势绘制监听回调。
OnGesturePerformedListener 是手势已经形成回调的API。大致的使用方法以及意义了解之后就写一个简单的实例。
MainActivity,很多逻辑都写了注释。
package com.example.administrator.myapplication;
import android.content.DialogInterface;
import android.content.Intent;
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.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity
EditText editText;
GestureOverlayView overlayView;
Button button;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.editText);
overlayView = (GestureOverlayView) findViewById(R.id.gesture);
button = (Button) findViewById(R.id.btn);
//设置手势颜色
overlayView.setGestureColor(Color.RED);
//设置手势宽度
overlayView.setGestureStrokeWidth(10);
//获得手势的缓存
final GestureLibrary gestureLibrary = GestureLibraries.fromFile("/mnt/sdcard/mygestures");
//添加手势监听
overlayView.addOnGesturePerformedListener(new GestureOverlayView.OnGesturePerformedListener()
@Override
public void onGesturePerformed(GestureOverlayView gestureOverlayView, final Gesture gesture)
//加载提示界面
View save = getLayoutInflater().inflate(R.layout.save,null);
//获得提示界面的手势图片控件
ImageView imageView = (ImageView) save.findViewById(R.id.image);
final EditText editText = (EditText) save.findViewById(R.id.editText);
//将手势图片转码生成bitmap
Bitmap bitmap = gesture.toBitmap(128,128,10,0xffff0000);
imageView.setImageBitmap(bitmap);
//提示设置
new AlertDialog.Builder(MainActivity.this)
.setView(save)
.setPositiveButton("保存", new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialogInterface, int i)
//点击
addGesture(gestureLibrary,editText,gesture);
).setNegativeButton("取消",null).show();
);
button.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
startActivity(new Intent(MainActivity.this,GestureActivity.class));
);
private void addGesture(GestureLibrary gestureLibrary, EditText editText, Gesture gesture)
//添加手势
gestureLibrary.addGesture(editText.getText().toString(),gesture);
//判断是否保存成功
if (gestureLibrary.save())
Toast.makeText(MainActivity.this, "保存成功!", Toast.LENGTH_SHORT).show();
else
Toast.makeText(MainActivity.this, "保存失败!", Toast.LENGTH_SHORT).show();
//调用保存
gestureLibrary.save();
我的主界面布局。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.administrator.myapplication.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="绘制自己的手势" />
<android.gesture.GestureOverlayView
android:id="@+id/gesture"
android:layout_centerInParent="true"
android:layout_width="200dp"
android:layout_height="220dp"
android:gestureStrokeType="multiple">
</android.gesture.GestureOverlayView>
<LinearLayout
android:layout_marginTop="20dp"
android:layout_centerInParent="true"
android:orientation="vertical"
android:layout_width="200dp"
android:layout_height="220dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/num0"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="40dp"
android:src="@drawable/circle"/>
<ImageView
android:id="@+id/num1"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="40dp"
android:src="@drawable/circle"/>
<ImageView
android:id="@+id/num2"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="40dp"
android:src="@drawable/circle"/>
</LinearLayout>
<LinearLayout
android:layout_marginTop="40dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/num3"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="40dp"
android:src="@drawable/circle"/>
<ImageView
android:id="@+id/num4"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="40dp"
android:src="@drawable/circle"/>
<ImageView
android:id="@+id/num5"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="40dp"
android:src="@drawable/circle"/>
</LinearLayout>
<LinearLayout
android:layout_marginTop="40dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/num6"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="40dp"
android:src="@drawable/circle"/>
<ImageView
android:id="@+id/num7"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="40dp"
android:src="@drawable/circle"/>
<ImageView
android:id="@+id/num8"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="40dp"
android:src="@drawable/circle"/>
</LinearLayout>
</LinearLayout>
<Button
android:id="@+id/btn"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="识别手势库"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
save.xml的布局。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="输入名称:"/>
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<ImageView
android:id="@+id/image"
android:layout_gravity="center_horizontal"
android:layout_width="128dp"
android:layout_height="128dp"
android:layout_marginTop="10dp"/>
</LinearLayout>
手势从手势库加载,并进行识别。
package com.example.administrator.myapplication;
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.util.Log;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import java.util.ArrayList;
public class GestureActivity extends AppCompatActivity
GestureOverlayView gesture_test;
GestureLibrary gestureLibrary;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gesture);
gesture_test = (GestureOverlayView) findViewById(R.id.gesture_test);
gestureLibrary = GestureLibraries.fromFile("/mnt/sdcard/mygestures");
if (gestureLibrary.load())
Toast.makeText(this, "文件手势加载成功。", Toast.LENGTH_SHORT).show();
else
Toast.makeText(this, "文件手势加载失败。", Toast.LENGTH_SHORT).show();
gesture_test.addOnGesturePerformedListener(new GestureOverlayView.OnGesturePerformedListener()
@Override
public void onGesturePerformed(GestureOverlayView gestureOverlayView, Gesture gesture)
ArrayList<Prediction> predictions = gestureLibrary.recognize(gesture);
ArrayList<String> result = new ArrayList<String>();
Log.i("tag00","数据库一共多少个手势:"+predictions.size());
for (Prediction prediction:predictions)
Log.i("tag00","手势:"+prediction.name +",相似度:"+prediction.score);
// if (prediction.score > 2.0)
result.add("与手势【" + prediction.name + "】相似度为" + prediction.score);
//
if (result.size() > 0)
ArrayAdapter adapter = new ArrayAdapter(GestureActivity.this,android.R.layout.simple_dropdown_item_1line,result.toArray());
new AlertDialog.Builder(GestureActivity.this).setAdapter(adapter,null).setPositiveButton("确定",null).show();
else
Toast.makeText(GestureActivity.this, "无法找到能匹配的手势!", Toast.LENGTH_SHORT).show();
);
识别界面非常简单。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_gesture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.administrator.myapplication.GestureActivity">
<android.gesture.GestureOverlayView
android:id="@+id/gesture_test"
android:layout_width="match_parent"
android:layout_height="match_parent"></android.gesture.GestureOverlayView>
</RelativeLayout>
记得添加权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
由于这个是手势相关的,模拟器不太好运行,真机做一个gif也比较麻烦。以上代码我已经测试没有问题。可以直接使用。这些就是手势的简单自定义和识别。
以上是关于Android基础系列 - 手势自定义,识别手势的主要内容,如果未能解决你的问题,请参考以下文章
Android应用开发基础篇(13)-----GestureDetector(手势识别)