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这是因为人的动作不标准所致。

    <完>

  • 相关阅读:
    大数加法、乘法实现的简单版本
    hdu 4027 Can you answer these queries?
    zoj 1610 Count the Colors
    2018 徐州赛区网赛 G. Trace
    1495 中国好区间 尺取法
    LA 3938 动态最大连续区间 线段树
    51nod 1275 连续子段的差异
    caioj 1172 poj 2823 单调队列过渡题
    数据结构和算法题
    一个通用分页类
  • 原文地址:https://www.cnblogs.com/zhoug2020/p/6105922.html
Copyright © 2011-2022 走看看