How to distinguish between move and click in onTouchEvent()?

后端 未结 10 2147
暖寄归人
暖寄归人 2020-11-28 22:30

In my application, I need to handle both move and click events.

A click is a sequence of one ACTION_DOWN action, several ACTION_MOVE actions and one ACTION_UP action

10条回答
  •  半阙折子戏
    2020-11-28 23:16

    Taking Jonik's lead I built a slightly more fine tuned version, that doesn't register as a click if you move your finger and then return to the spot before letting go:

    So here is my solution:

    /**
     * Max allowed duration for a "click", in milliseconds.
     */
    private static final int MAX_CLICK_DURATION = 1000;
    
    /**
     * Max allowed distance to move during a "click", in DP.
     */
    private static final int MAX_CLICK_DISTANCE = 15;
    
    private long pressStartTime;
    private float pressedX;
    private float pressedY;
    private boolean stayedWithinClickDistance;
    
    @Override
    public boolean onTouchEvent(MotionEvent e) {
         switch (e.getAction()) {
            case MotionEvent.ACTION_DOWN: {
                pressStartTime = System.currentTimeMillis();                
                pressedX = e.getX();
                pressedY = e.getY();
                stayedWithinClickDistance = true;
                break;
            }
            case MotionEvent.ACTION_MOVE: {
                if (stayedWithinClickDistance && distance(pressedX, pressedY, e.getX(), e.getY()) > MAX_CLICK_DISTANCE) {
                    stayedWithinClickDistance = false;
                }
                break;
            }     
            case MotionEvent.ACTION_UP: {
                long pressDuration = System.currentTimeMillis() - pressStartTime;
                if (pressDuration < MAX_CLICK_DURATION && stayedWithinClickDistance) {
                    // Click event has occurred
                }
            }     
        }
    }
    
    private static float distance(float x1, float y1, float x2, float y2) {
        float dx = x1 - x2;
        float dy = y1 - y2;
        float distanceInPx = (float) Math.sqrt(dx * dx + dy * dy);
        return pxToDp(distanceInPx);
    }
    
    private static float pxToDp(float px) {
        return px / getResources().getDisplayMetrics().density;
    }
    

提交回复
热议问题