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();
                }
            }
        });

 

 

 

 

posted @ 2016-04-22 12:08  maozs  阅读(539)  评论(0编辑  收藏  举报