android手势识别
一、简单手势识别:
简单手势识别分为以下几个步骤:
1.手指触碰屏幕时,触发MotionEvent事件;
2.该事件被OnTouchListener监听,可在它的onTouch()方法中获得该MotionEvent对象;
3.通过GestureDetector转发MotionEvent对象给OnGestureListener;
4.我们可以通过OnGestureListener获得该对象,然后获取相关信息,以及做相关处理。
MotionEvent中封装了手势动作事件和x、y坐标信息。
GestureDetector对手势进行加工,交给GestureListener进行处理。
GestureDetector提供了OnDoubleTapListener、OnGestureListener两种监听器,同时提供了SimpleOnGestureListener类进行适配,让我们选择需要的接口进行实现。
我们主要的工作就在步骤4,在GestureListener中对用户的手势操作进行分析和处理。
GestureListener有以下回调接口:
onDown: 按下,只要手指触碰即触发。
onFling: 快速滑动并松开。
onLongPress: 长按。
onScroll: 滑动。
onShowPress: 短按。
onSingleTapUp:抬起。
OnDoubleTapListener有以下接口:
onSingleTapConfirmed :单击。
onDoubleTap :双击
onDoubleTapEvent:双击中的第二次按下后事件触发。
下面是简单的测试代码:
public class MainActivity extends AppCompatActivity { private ImageView iv; private GestureDetector gestureDetector; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gestureDetector=new GestureDetector(this,new MyGestureLsn()); iv= (ImageView) findViewById(R.id.iv); iv.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { gestureDetector.onTouchEvent(event); return true; } }); } class MyGestureLsn extends GestureDetector.SimpleOnGestureListener{ @Override public boolean onSingleTapUp(MotionEvent e) { Show.log("onSingleTapUp"); return super.onSingleTapUp(e); } @Override public void onLongPress(MotionEvent e) { Show.log("onLongPress"); super.onLongPress(e); } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { Show.log("onScroll"); return super.onScroll(e1, e2, distanceX, distanceY); } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { Show.log("onFling"); return super.onFling(e1, e2, velocityX, velocityY); } @Override public void onShowPress(MotionEvent e) { Show.log("onShowPress"); super.onShowPress(e); } @Override public boolean onDown(MotionEvent e) { Show.log("onDown"); return super.onDown(e); } @Override public boolean onDoubleTap(MotionEvent e) { Show.log("onDoubleTap"); return super.onDoubleTap(e); } @Override public boolean onDoubleTapEvent(MotionEvent e) { Show.log("onDoubleTapEvent"); return super.onDoubleTapEvent(e); } @Override public boolean onSingleTapConfirmed(MotionEvent e) { Show.log("onSingleTapConfirmed"); return super.onSingleTapConfirmed(e); } } }
二、复杂手势识别
1.生成手势库文件
android提供了GestureOverlayView类用于复杂手势的识别,首先得创建手势库文件,建议用谷歌提供的一个工具——GestureBuilder项目来生成,
当然也可以自己创建一个项目来生成,下面是一段创建手势库的简单代码:
GestureOverlayView gesture = (GestureOverlayView) findViewById(R.id.gesture); gesture.setGestureColor(Color.GREEN); gesture.setGestureStrokeWidth(5); gesture.addOnGesturePerformedListener(new GestureOverlayView.OnGesturePerformedListener() { @Override public void onGesturePerformed(GestureOverlayView gestureOverlayView, final Gesture gesture) { View saveDialog = getLayoutInflater().inflate(R.layout.dialog_save, null, false); ImageView img_show = (ImageView) saveDialog.findViewById(R.id.img_show); Bitmap bitmap = gesture.toBitmap(128, 128, 10, 0xffff0000); img_show.setImageBitmap(bitmap); new AlertDialog.Builder(MainActivity.this).setView(saveDialog) .setPositiveButton("保存", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { //获取文件对应的手势库 GestureLibrary gestureLib = GestureLibraries.fromFile("/mnt/sdcard/gestures"); gestureLib.addGesture("gesture name", gesture); gestureLib.save(); } }).setNegativeButton("取消", null).show(); } });
每个手势都对应一个名字,为了防止识别错误,最好让各个手势之间的差别足够大。
2.识别
首先得将手势库文件导入到项目中,然后在将新手势和手势库中的进行匹配:
GestureLibrary gestureLibrary = GestureLibraries.fromRawResource(this, R.raw.gestures); if (gestureLibrary.load()) { //加载成功 } else { //加载失败 } GestureOverlayView gesture = (GestureOverlayView) findViewById(R.id.gesture); gesture.setGestureColor(Color.GREEN); gesture.setGestureStrokeWidth(5); gesture.addOnGesturePerformedListener(new GestureOverlayView.OnGesturePerformedListener() { @Override public void onGesturePerformed(GestureOverlayView gestureOverlayView, final Gesture gesture) { //识别用户刚绘制的手势 ArrayList<Prediction> predictions = gestureLibrary.recognize(gesture); ArrayList<String> result = new ArrayList<String>(); //遍历所有找到的Prediction对象 for (Prediction pred : predictions) { if (pred.score > 1.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()); new AlertDialog.Builder(MainActivity.this).setAdapter(adapter, null).setPositiveButton("确定", null).show(); } else { Toast.makeText(MainActivity.this, "无法找到匹配的手势!", Toast.LENGTH_SHORT).show(); } } });