Android中的双击事件

作者: 尹star | 来源:发表于2016-05-09 13:25 被阅读7204次

一般来说Android用户比较熟悉的按钮交互方式有两种:单击与长按。双击这个交互且不说合不合理,但需求来了总是要做的。关于这个交互,最先想到的是Android手机系统中,连续点击版本号6次可以打开开发者模式这一场景。这个场景比较简单,只需要计数就好,而我这里的需求,同一个按钮,单击与双击会触发不同的事件。
出于职业嗅觉,首先考虑的是有没有相关API可以调用,查阅了一下,果然找到GestureDetector.OnDoubleTapListener这个接口正适合目前的需求。OnDoubleTapListener的间接子类叫SimpleOnGestureListener,我只需要重写下按钮的onTouch事件,在重写方法里做事件分发即可,于是乎问题迎刃而解:

button.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return gestureDetector.onTouchEvent(event);
            }
        });

      GestureDetector gestureDetector = new GestureDetector(Activity.this, new GestureDetector.SimpleOnGestureListener() {

            /**
             * 发生确定的单击时执行
             * @param e
             * @return
             */
            @Override
            public boolean onSingleTapConfirmed(MotionEvent e) {//单击事件

                Toast.makeText(Activity.this,"这是单击事件", Toast.LENGTH_SHORT).show();
                return super.onSingleTapConfirmed(e);
            }

            /**
             * 双击发生时的通知
             * @param e
             * @return
             */
            @Override
            public boolean onDoubleTap(MotionEvent e) {//双击事件
                Toast.makeText(Activity.this,"这是单击事件",Toast.LENGTH_SHORT).show();
                return super.onDoubleTap(e);
            }

            /**
             * 双击手势过程中发生的事件,包括按下、移动和抬起事件
             * @param e
             * @return
             */
            @Override
            public boolean onDoubleTapEvent(MotionEvent e) {
                return super.onDoubleTapEvent(e);
            }
        });

假如没有这样的API,我们要自己实现,可以怎么做呢。这里比较绕的地方就是单击和双击事件都要照顾,但二者又有联系和冲突,然后我想了个办法,通过Hander发送不同的消息来标记两个事件,两次点击之间如果小于某个时间差,就认为触发双击事件,单击事件消息的发送延迟略长于这个时间差,如果在这之间触发了双击事件,就撤回单击事件的消息发送,这样单击就不会被执行,代码如下。

public class MainActivity extends Activity {


    long mLastTime=0;
    long mCurTime=0;

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 1:
                    Toast.makeText(MainActivity.this,"这是单击事件",Toast.LENGTH_LONG).show();
                    break;
                case 2:
                    Toast.makeText(MainActivity.this,"这是双击事件",Toast.LENGTH_LONG).show();
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                mLastTime=mCurTime;
                 mCurTime= System.currentTimeMillis();
                if(mCurTime-mLastTime<300){//双击事件
                    mCurTime =0;
                    mLastTime = 0;
                    handler.removeMessages(1);
                    handler.sendEmptyMessage(2);
                }else{//单击事件
                    handler.sendEmptyMessageDelayed(1, 310);
                }
            }
        });
    }
}

跑起来也没什么问题,很OK的样子,不知道大家有没有其他的好办法,可以交流讨论。

相关文章

网友评论

  • xiaoc024:你们不重写onDown(MotionEvent e){return true},真的能收到双击回调吗???https://stackoverflow.com/questions/11463854/ondoupletap-does-not-fire
  • GcsSloop:GestureDetector 中有相关方法,如下:
    GestureDetector detector = new GestureDetector(this, new GestureDetector
    .SimpleOnGestureListener() {
    @Override public boolean onSingleTapConfirmed(MotionEvent e) {
    Toast.makeText(MainActivity.this, "单击", Toast.LENGTH_SHORT).show();
    return false;
    }
    @Override public boolean onDoubleTap(MotionEvent e) {
    Toast.makeText(MainActivity.this, "双击", Toast.LENGTH_SHORT).show();
    return false;
    }
    });
  • one1go:在使用GestureDetector 的时候出现空指针异常,没发现出现问题的地方在哪里:sweat:
  • Zack_zhou:有一个笔误,两个Toast都是“这是单击事件”,我就纳闷了我怎么点提示的都是单击事件
  • Aegis:官方做法是拷贝数组
  • 82f7d163c7c2:其实看这个类的源码就行了,时间这个最好用安卓的系统常量,否则就会造成和系统组件的手势冲突
  • 当时我就懵逼了:GestureDetector 不能定义间隔时间,
    第二种的话,单击事件要延迟300ms才执行,有没有其他好的方法?
    当时我就懵逼了:@尹star 确实是这样,单击和双击并存的话,GestureDetector的单击也是有延迟的,看来要合理控制这个间隔时间,谢谢
    尹star:@当时我就懵逼了 如果单击双击事件并存, 单击事件必然会延迟的,因为你不确定本次点击到底是单击还是双击,所以就要等等看后面还有没有新的触发,即便用GestureDetector ,单击事件也有延迟的,可以试试。

本文标题:Android中的双击事件

本文链接:https://www.haomeiwen.com/subject/pmwjrttx.html