zoukankan      html  css  js  c++  java
  • Android: 触屏fling/scroll/drag的区别及其详细过程

    Google了一下,终于搞清了touch screen下的几种操作模式(对应的是事件)。

    对于一个view, 常用的操作有点击(click)和长按(long press)二种。实际上,这些操作类型是Android内部在onTouchEvent(MotionEvent event)里对用户的动作做了一定的分析,从而通知应用程序是发生了点击还是长按等事件。

    有时,我们需要的并不仅限于这两种操作。我们可以借助GestureDetector来分析出更细致的操作类型。基本的过程就是创建一个myGestureDetector对象,传入自己定义的myOnGestureListener对象,在自己的onTouchEvent回调函数中将接收到的event传给myGestureDetector进行分析,myOnGestureListener会回调我们定义的动作。
    【 从 GestureDetector.SimpleOnGestureListener派生出myListener 会更简单,因为这个类已经实现了全部接口,只是没有什么实际有用的功能。】

    参考以下代码(for an Activity):

    // -------------------------------------------------------------------------------

    private GestureDetector mGestureDetector;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); 
        mGestureDetector = new GestureDetector(this, new MyGestureListener());
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return mGestureDetector.onTouchEvent(event);
    }


    class MyGestureListener extends GestureDetector.OnGestureListener{ //共有6个方法:

        // 用户轻触触屏:Touch down(仅一次)时触发, e为down时的MotionEvent:
        boolean onDown(MotionEvent e){return true;}

        // 用户轻触触屏,且尚未松开或拖动
        //   在Touch down(仅一次)之后一定时间(115ms)触发,e为down时的MotionEvent:
        void onShowPress(MotionEvent e){return true;}

        // 用户(轻触触屏后)松开:Touch up(仅一次)时触发,e为up时的MotionEvent:
        boolean onSingleTapUp(MotionEvent e){return true;}

        // 用户轻触触屏,并拖动:
        //   按下并滑动时触发,e1为down(仅一次)时的MotionEvent,e2为move(多个)时的MotionEvent:
        boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY){return true;}

        // 用户长按触屏(此View必须是可长按的: myView->setLongClickable(true);):
        //   在Touch down之后一定时间(500ms)后,由多个down事件触发,e为down时的MotionEvent:
        void onLongPress(MotionEvent e){return true;}

        // 用户按下触屏、快速移动后松开:
        //   按下并快速滑动一小段距离(多个move),up时触发,e1为down(仅一次)时的MotionEvent,
        //   e2为up(仅一次)时的MotionEvent:
        boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY){return true;}
    }
    // -------------------------------------------------------------------------------

    至于doubletap的检测,可以通过设置mGestureDetector的OnDoubleTapListener来实现:

    GestureDetector.OnDoubleTapListener doubleTapListener = new GestureDetector.OnDoubleTapListener() {

        // 完成一次单击,并确定(300ms内)没有发生第二次单击事件后触发,e为down时的MotionEvent:
        boolean onSingleTapConfirmed(MotionEvent e){return true;}
     
        // 第二次单击down时触发,e为第一次down时的MotionEvent:
        boolean onDoubleTap(MotionEvent e){return true;}

        // 第二次单击down、move和up时都触发,e为不同时机下的MotionEvent:
        boolean onDoubleTapEvent(MotionEvent e){return true;}
    }
    mGestureDetector.setDoubleTapListener(doubleTapListener);
    // -------------------------------------------------------------------------------


    具体地说,典型的触屏事件及其listener执行的流程见下:

    1). 单击事件的执行流程:
      有两种情况,一种是时间很短,一种时间稍长。
      时间很短:onDown ----> onSingleTapUp ----> onSingleTapConfirmed
      时间稍长:onDown ----> onShowPress   ----> onSingleTapUp ----> onSingleTapConfirmed

    2). 长按事件
       onDown ----> onShowPress ----> onLongPress

    3.抛(fling):手指触动屏幕后,稍微滑动后立即松开:
       onDown ----> onScroll ----> onScroll ----> onScroll ----> ………  ----> onFling

    4.拖动(drag)
       onDown ----> onScroll ----> onScroll ----> onFiling
       注意:有的时候会触发onFiling,但是有的时候不会触发,z这是因为人的动作不标准所致。

    <完>

  • 相关阅读:
    5.4 省选模拟赛 修改 线段树优化dp 线段树上二分
    一本通 高手训练 1782 分层图 状压dp
    luogu P3830 [SHOI2012]随机树 期望 dp
    5.2 省选模拟赛 或许 线型基
    luogu P4562 [JXOI2018]游戏 组合数学
    一本通 高手训练 1781 死亡之树 状态压缩dp
    luogu P4726 【模板】多项式指数函数 多项式 exp 牛顿迭代 泰勒展开
    4.28 省选模拟赛 负环 倍增 矩阵乘法 dp
    HDU 1756 Cupid's Arrow 计算几何 判断一个点是否在多边形内
    一本通 高手训练 1763 简单树 可持久化线段树 树链刨分 标记永久化
  • 原文地址:https://www.cnblogs.com/zhoug2020/p/6105922.html
Copyright © 2011-2022 走看看