zoukankan      html  css  js  c++  java
  • Android Touch 事件总结

    ---恢复内容开始---

    1.Touch事件传递机制

      过程有点儿类似于栈, ViewGroup的子类有都继承它的以下3个方法:

      public boolean dispatchTouchEvent(MotionEvent event);  //消息分发, 相当于在一个函数中调用其他函数

      public boolean onInterceptTouchEvent(MotionEvent event); // 拦截消息

      public boolean onTouchEvent(MotionEvent event);    // 触屏处理, 如果完成处理则返回true, 相当于break直接退出消息处理,如果没有完成处理则返回false, 返回到分发消息给它的View控件的onTouchEvent()继续进行递归处理.制定返回到消息来源处

      消息往下分发称为隧道方式, 触屏消息在子视图中没有处理完传递给上层控件,称为冒泡方式.

    2.区别onTouch() 和 onTouchEvent()

      onTouch(): 定义在接口OnTouchListener中, 绑定触屏监听器后覆写这个方法实现自定义触屏行为

      onTouchEvent(): Activity 中的方法, 当屏幕有触摸事件时调用这个方法, 如果一直按着屏幕,就会一直循环调用,我的电脑上大概几十毫秒调用一次,不过这个不用管. 当然, onTouch()方法也会在你一直按着绑定的控件的时候一直循环调用.

    3.onTouchEvent()处理的消息

      onTouchEvent()方法是从Activity中继承下来的, 所以只需要在Activity中覆写就可以了, 它处理以下3种消息

      1) 屏幕按下: MotionEvent.ACTION_DOWN

      2) 从屏幕上释放: MotionEvent.ACTION_UP

      3) 在屏幕上移动: MotionEvent.ACTION_MOVE

     1 @Override
     2 public boolean onTouchEvent(MotionEvent event) {
     3     int[] events = {
     4             MotionEvent.ACTION_DOWN,
     5             MotionEvent.ACTION_MOVE,
     6             MotionEvent.ACTION_UP,
     7             MotionEvent.ACTION_CANCEL,
     8             MotionEvent.ACTION_OUTSIDE,
     9             MotionEvent.ACTION_POINTER_DOWN,
    10             MotionEvent.ACTION_POINTER_UP,
    11             MotionEvent.EDGE_TOP,
    12             MotionEvent.EDGE_BOTTOM,
    13             MotionEvent.EDGE_LEFT,
    14             MotionEvent.EDGE_RIGHT
    15     };
    16     String[] szEvent = {
    17             "MotionEvent.ACTION_DOWN",
    18             "MotionEvent.ACTION_MOVE",
    19             "MotionEvent.ACTION_UP",
    20             "MotionEvent.ACTION_CANCEL",
    21             "MotionEvent.ACTION_OUTSIDE",
    22             "MotionEvent.ACTION_POINTER_DOWN",
    23             "MotionEvent.ACTION_POINTER_UP",
    24             "MotionEvent.EDGE_TOP",
    25             "MotionEvent.EDGE_BOTTOM",
    26             "MotionEvent.EDGE_LEFT",
    27             "MotionEvent.EDGE_RIGHT"
    28     };
    29     for(int i=0;i<events.length;++i){
    30         if(events[i] == event.getAction()){
    31             Log.v(TAG,szEvent[i]);
    32             break;
    33         }
    34     }
    35     return super.onTouchEvent(event);
    36 }

      将上面的方法覆盖Activity的方法即可, 值得注意的是,MOVE事件会在你点击释放过程中触发, 而且触发多次! 所以在手势识别过程部分函数参数会只记录最后一个MOVE事件

    4.手势识别: android.view.GestureDetector类 + OnGestureListener接口

      里面有很多方法,覆写之后可以实现多种触屏效果, 增加用户体验

      使用GestureDetector对象,为这个对象添加一个监听器,并覆写方法. 这个对象可以作为Activity的属性, 当然也就是最这个Activity进行手势解析了.然后再覆写Activity的onTouchEvent方法, 对触屏事件进行监听即可.

     1 private GestureDetector gestureDetector = new GestureDetector(new GestureDetector.OnGestureListener() {
     2     @Override
     3     public boolean onDown(MotionEvent e) {
     4         // 按下屏幕的时候
     5         Toast.makeText(MainActivity.this,"onDown",Toast.LENGTH_SHORT).show();
     6         Log.v(TAG,"onDown");
     7         return false;
     8     }
     9 
    10     @Override
    11     /**
    12      * 点击了屏幕, 但是没有移动和弹起动作. 与onDown的区别:
    13      *      onDown():一旦按下屏幕,就尝试onDown事件
    14      *      onShowPress(): onDown事件产生后,一段时间内没有移动和弹起(先产生了onDown事件)
    15      *
    16      */
    17     public void onShowPress(MotionEvent e) {
    18         Log.v(TAG,"onShowPress");
    19         Toast.makeText(MainActivity.this,"onShowPress",Toast.LENGTH_SHORT).show();
    20     }
    21 
    22     @Override
    23     /**
    24      * 轻击触摸屏和弹起,这个过程中如果产生了onLongPress,onScroll 和 onFling事件,就不会产生onSingleTabUp事件
    25      */
    26     public boolean onSingleTapUp(MotionEvent e) {
    27         Log.v(TAG,"onSingleTabUp");
    28         Toast.makeText(MainActivity.this, "onSingleTagUp", Toast.LENGTH_SHORT).show();
    29         return false;
    30     }
    31 
    32     @Override
    33     /**
    34      * 滚动事件, 当在屏幕上迅速移动,会产生onScroll,由ACTION_MOVE产生
    35      * @param: distanceX: 距离上次产生onScroll事件后, X轴的移动距离
    36      */
    37     public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
    38         Log.v(TAG,"onScroll");
    39         Toast.makeText(MainActivity.this, "onScroll", Toast.LENGTH_SHORT).show();
    40         return false;
    41     }
    42 
    43     @Override
    44     public void onLongPress(MotionEvent e) {
    45         Log.v(TAG,"onLongPress");
    46         Toast.makeText(MainActivity.this, "onLongPress", Toast.LENGTH_SHORT).show();
    47     }
    48 
    49     @Override
    50     /**
    51      * @param: e1: 第一个ACTION_DOWN MotionEvent
    52      * @param: e2: 最后一个ACTION_MOVE MotionEvent
    53      * @param: velocityX: X轴上的移动速度  px/s
    54      * @param: velocityY: Y轴上的移动速度
    55      */
    56     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
    57         Log.v(TAG,"onFling");
    58         Toast.makeText(MainActivity.this, "onFling", Toast.LENGTH_SHORT).show();
    59 
    60         return false;
    61     }
    62 });
    63 
    64 @Override
    65 public boolean onTouchEvent(MotionEvent event) {
    66     Log.v(TAG,"onTouchEvent");
    67     if(gestureDetector.onTouchEvent(event)){
    68         return true;
    69     }else{
    70       return super.onTouchEvent(event); //未完成处理交给上层控件
    71     }
    72 }

    5.处理键盘事件

      覆写Activity的onKeyDown()即可,有的需要在AndroidManifest.xml文件中添加权限...

     1 public boolean onKeyUp(int keyCode, KeyEvent event) {
     2     switch (keyCode){
     3         case KeyEvent.KEYCODE_HOME: //好像说不再支持了,需要修改框架源码实现,有点儿复杂,期待新发现
     4             Log.v(TAG,"HOME up");
     5             break;
     6         case KeyEvent.KEYCODE_BACK:
     7             Log.v(TAG,"BACK up");
     8             break;
     9         case KeyEvent.KEYCODE_DPAD_LEFT:
    10             Log.v(TAG,"Left up");
    11             break;
    12     }
    13 //        return  true;
    14     return super.onKeyUp(keyCode, event);
    15 }
  • 相关阅读:
    重学Java 面向对象 之 final
    java并发学习04---Future模式
    java并发学习03---CountDownLatch 和 CyclicBarrier
    java并发学习02---ReadWriteLock 读写锁
    java并发学习01 --- Reentrantlock 和 Condition
    链表的倒数第k个节点
    重建二叉树
    java并发学习--线程池(一)
    二叉树的深度
    vue-常用指令(v-for)
  • 原文地址:https://www.cnblogs.com/roger9567/p/4488962.html
Copyright © 2011-2022 走看看