zoukankan      html  css  js  c++  java
  • Android攻城狮GestureDetector和GestureOverlayView

    手势识别
    可以通过以下两种方式实现:
    1. 使用GestureDetector
    2. 使用GestureOverlayView(属于线程的控件)
    
    手势交互过程(原理):
    1. 触屏一刹那,触发 MotionEvent 事件;
    2. 被 OnTouchListener 监听,在 onTouch()中获得 MotionEvent对象;
    3. GestureDetector 转发 MotionEvent 对象至 OnGestureListener;
    4. OnGestureListener 获取该对象,根据该对象封装的信息做出合适的反馈;
    
    MotionEvent:
    1. 用于封装手势、触摸笔、轨迹球等动作事件;
    2. 内部封装用于记录横轴和纵轴坐标的属性X和Y。
    GestureDetector:
    识别各种手势。
    OnGestureListener:
    1. 手势交互的监听接口,其提供多个抽象方法;
    2. 根据 GestureDetector 的手势识别结果,调用相应的方法。
    
    GestureDetector 详解:
    触摸屏:按下、移动、抬起等。
    监听触摸事件:重载 onTouch 或者设置 setOnTouchListener
    GestureDetector 工作原理:
    1. 当接收到用户触摸消息时,将消息交给 GestureDetector加工;
    2. 通过设置监听器获得 GestureDetector 处理后的手势。
    GestureDetector提供两个监听器:
    1. OnGestureListener:处理单击类消息
    2. OnDoubleTapListener:处理双击类消息

    OnGestureListener接口的6个方法:
    单击:onDown(MotionEvent e)
    抬起:onSingleTapUp(MotionEvent e)
    短按:onShowPress(MotionEvent e)
    长按:onLongPress(MotionEvent e)
    滚动:onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float disanceY)
    滑动:onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
    (注解:velocity:速率,速度)
    
    OnDoubleTapListener接口的3个方法:
    双击:onDoubleTap(MotionEvent e)
    双击按下和抬起各触发一次:onDoubleTapEvent(MotionEvent e)
    单击确认:onSingleTapConfirmed(MotionEvent e)就是很快地按下并抬起,但不连续点击第二下。
    
    如果分别去实现这两个接口的所有方法,未免太麻烦了,所以这里提供了另一个接口:SimpleOnGestureListener,它已经继承了前面所讲的两个监听器。
    - 继承SimpleOnGestureListener
    - 重载感兴趣的手势
     1 public class MainActivity extends Activity {
     2     ImageView imageView;
     3     GestureDetector myDetector;
     4 
     5     class myGestureListenner extends SimpleOnGestureListener {
     6         @Override
     7         // e1表示起始事件,e2表示末尾事件,每个事件都含有坐标属性。通过起止事件的相对位置,可以判断是从左往右滑动还是从右往左滑动。
     8         public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
     9                 float velocityY) {
    10             // TODO Auto-generated method stub
    11             if (e1.getX() - e2.getX() > 50) {
    12                 Toast.makeText(MainActivity.this, "从右边往左边滑动!", 0).show();
    13 
    14             } else if (e2.getX() - e1.getX() > 50) {
    15                 Toast.makeText(MainActivity.this, "从左边往右边滑动!", 0).show();
    16             }
    17             return super.onFling(e1, e2, velocityX, velocityY);
    18         }
    19 
    20     }
    21 
    22     @Override
    23     protected void onCreate(Bundle savedInstanceState) {
    24         super.onCreate(savedInstanceState);
    25         setContentView(R.layout.fragment_main);
    26         imageView = (ImageView) findViewById(R.id.image);
    27         myDetector = new GestureDetector(new myGestureListenner());
    28         imageView.setOnTouchListener(new OnTouchListener() {
    29 
    30             @Override
    31             public boolean onTouch(View v, MotionEvent event) {
    32                 // TODO Auto-generated method stub
    33                 // 捕获触摸屏幕的Event事件
    34                 myDetector.onTouchEvent(event);
    35 
    36                 return true;
    37             }
    38         });
    39     }
    40 
    41 }
    使用GestureOverlayView进行手势识别的步骤:
    1. 使用Gesture Builder生成手势文件
    2. 将文件加入到项目
    3. 在项目中创建 GestureOverlayView,将它放置在想要识别手势的控件上,或者把它包裹起来。
    
    只能识别文件中存在的手势,如果不是文件中存在的手势,就无法识别。
    ---------------
    在res文件夹下创建文件夹raw,把手势文件gesture添加到这里。
    GestureOverlayView
    一种用于手势输入的透明覆盖层,可覆盖在其他控件的上方,也可以包含其他控件。存在3个监听接口:
    GestureOverlayView.OnGestureListener    // 手势监听器
    GestureOverlayView.OnGesturePerformedListener    // 手势执行监听器
    GestureOverlayView.OnGesturingListener    // 手势执行中监听器
    ------------------
    如图使用GestureOverlayView控件去包含ImageView控件。
    可识别手势的区域大小不是由ImageView决定,而是由GestureOverlayView决定。
    ------------------------
    补充:
    使用Android Studio则更加简单,不用去创建 Simple Project。老师之所以要创建Simple Project,是因为模拟器中没有Gesture Builder这种应用,所以要自己创建。而Android Studio的模拟器是有Gesture Builder的,所以我们可以直接进入模拟器,点击Gesture Builder图标,进行手势的创建。
    
    
    给gestureOverlayView设置监听器:
    gestureOverlayView.addOnGesturePerformedListener(new OnGesturePerformedListener(){})
    重写方法onGesturePerformed()。
    如图,onGesturePerformed()的示例代码,也就是关于手势识别的代码实现。
    ArrayList<Prediction>:预测集
    predction.score:相似度,值越大,则越相似,也就是说你必须做出几乎一模一样的手势才能通过识别。相似度的取值范围一般是0.0~10.0,取10.0就已经太夸张了,因为很难做出非常接近的手势。所以,这里的下限只取5.0:
    predction.score>=5.0
    如果觉得显示的手势的轨迹不好看,可以自定义轨迹的样式。
    一些常见的XML属性设置:
    Android:eventInterceptionEnabled  定义当手势已经被识别出来时,是否拦截该手势动作
    Android:fadeDuration  当用户画完的时候,手势效果淡出的时间
    Android:fadeEnabled  用户画完之后,手势是否自动淡出
    Android:gestureColor  手势的颜色
    Android:gestureStrokeType  笔画的类型
    Android:gestureStrokeWidth  笔画的粗细
     1 public class MainActivity extends ActionBarActivity {
     2     GestureOverlayView gestureOverlayView;
     3 
     4     @Override
     5     protected void onCreate(Bundle savedInstanceState) {
     6         super.onCreate(savedInstanceState);
     7         setContentView(R.layout.fragment_main);
     8         gestureOverlayView = (GestureOverlayView) findViewById(R.id.gestureOverlayView1);
     9         // 1.找到预设定的手势文件
    10         // 2.加载那个手势文件中的所有手势
    11         // 3.匹配,识别
    12 
    13         // 从资源中将手势库文件加载进来
    14         final GestureLibrary library = GestureLibraries.fromRawResource(
    15                 MainActivity.this, R.raw.gestures);
    16         library.load();
    17         gestureOverlayView
    18                 .addOnGesturePerformedListener(new OnGesturePerformedListener() {
    19 
    20                     @Override
    21                     public void onGesturePerformed(GestureOverlayView overlay,
    22                             Gesture gesture) {
    23                         // TODO Auto-generated method stub
    24                         // 读出手势库中内容 识别手势
    25                         ArrayList<Prediction> mygesture = library
    26                                 .recognize(gesture);
    27                         Prediction prediction = mygesture.get(0);
    28                         if (prediction.score >= 5.0) {
    29                             if (prediction.name.equals("exit")) {
    30                                 finish();
    31                             }
    32                             if (prediction.name.equals("next")) {
    33                                 Toast.makeText(MainActivity.this, "下一首", 0)
    34                                         .show();
    35                             }
    36                             if (prediction.name.equals("previouse")) {
    37                                 Toast.makeText(MainActivity.this, "上一首", 0)
    38                                         .show();
    39                             }
    40                         } else {
    41                             Toast.makeText(MainActivity.this, "没有该手势", 0)
    42                                     .show();
    43                         }
    44 
    45                     }
    46                 });
    47 
    48     }
    49 
    50 }




  • 相关阅读:
    (转)社会青年应如何自学英语?
    WEB标准学习路程之"CSS":13.声明,单位
    8大致命生活毛病(转)
    VS2008小Bug??
    【细嚼慢咽大数据】第一章——数据挖掘基本概念,邦弗朗尼原理,IF.IDF指标,哈希函数
    【Linux操作系统分析】定时测量——RTC,TSC,PIT,jiffies,计时体系结构,延迟函数
    【Git】Git上传本地项目的命令以及nonfastforward updates were rejected的解决办法
    【Linux操作系统分析】Ubuntu12.04内核升级和添加系统调用
    【折腾ubuntu】Ubuntu12.04安装windows版本的福昕阅读器
    【二】zTree checkbox
  • 原文地址:https://www.cnblogs.com/my334420/p/6754432.html
Copyright © 2011-2022 走看看