android 完全区分double-tap 与 singal-tap 的方法
阅读原文时间:2023年07月10日阅读:2

需求:viewpager显示图片,需要在双击时对图片进行缩放,单击时在屏幕下方弹出popwindow,由于android的双击本质就是两次单击,但是又不想在双击时触发单击时的动作,所以就在网上各种搜解决办法,未果,经过苦思冥想,发现以下办法

1.重写activity的dispatchTouchEvent方法

@Override
public boolean dispatchTouchEvent(MotionEvent event) {

     if (event.getAction() == MotionEvent.ACTION\_DOWN) {  
         mDownX = (int) event.getX();  
         if (mFirstTouchEventTime == 0) {  
             mFirstTouchEventTime = event.getDownTime();  
         } else {  
             mLastTouchEventTime = event.getDownTime();  
         }  
     } else if (event.getAction() == MotionEvent.ACTION\_UP) {  
         mUpX = (int) event.getX();  
         if (Math.abs(mUpX - mDownX) < 30) {  
             Log.d(TAG, "--->>" + Math.abs(mFirstTouchEventTime - mLastTouchEventTime));  
             if (Math.abs(mFirstTouchEventTime - mLastTouchEventTime) < Constants.TIME\_MENU\_DISPLAY) {  
                 mFirstTouchEventTime = 0L;  
                 mLastTouchEventTime = 0L;  
                 mScreenObsever.removeMessages(Constants.MSG\_MENU\_DISPLAY);  
             } else {  
                 mScreenObsever.sendEmptyMessageDelayed(Constants.MSG\_MENU\_DISPLAY, Constants.TIME\_MENU\_DISPLAY);  
             }  
         } else {  
             mFirstTouchEventTime = 0L;  
             mLastTouchEventTime = 0L;  
         }  
     }

     return super.dispatchTouchEvent(event);  
 }

其中 mFirstTouchEventTime 与 mLastTouchEventTime 为两个long型类变量,用来记录两次ACTION_DOWN动作发生的时间,Constants.TIME_MENU_DISPLAY 为一个自定义的msg what。mScreenObserver为一个自定义的handler,用来处理单击事件用。
2.mScreenObserver 的handler类实现

private class ObseverOperateHandler extends Handler {
@Override
public void handleMessage(Message msg) {

        if (msg.what == Constants.MSG\_MENU\_DISPLAY) {  
            mFirstTouchEventTime = 0L;  
            mLastTouchEventTime = 0L;  
            if (mOperateMenuPopupWindow.isShowing()) {  
                mNotePopWindow.startDownAnimation();  
                mOperateMenuPopupWindow.dismiss();  
            } else {  
                mNotePopWindow.startUpAnimation();  
                mOperateMenuPopupWindow.showAtLocation(findViewById(R.id.photoLayout), Gravity.BOTTOM, 0, 0);  
            }  
        }  
        super.handleMessage(msg);  
    }  
}

if 中的部分即是要在单击中处理的事情了

3.至于双击要做的事情,就可以正常实现GestureDetector.OnDoubleTapListener来处理了。网上就可以搜到怎么弄了。

另外代码中的Constants.TIME_MENU_DISPLAY这个时间值,经各种途径验证为350ms比较恰当,即两次单击间隔350ms会被认为是一次双击。