Anastasia Anastasia - 8 months ago 72
Android Question

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

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. In theory, if you get an ACTION_DOWN event and then an ACTION_UP event - it means that the user has just clicked your View.

But in practice, this sequence doesn't work on some devices. On my Samsung Galaxy Gio I get such sequences when just clicking my View: ACTION_DOWN, several times ACTION_MOVE, then ACTION_UP. I.e. I get some unexpectable OnTouchEvent firings with ACTION_MOVE action code. I never (or almost never) get sequence ACTION_DOWN -> ACTION_UP.

I also cannot use OnClickListener because it does not gives the position of the click. So how can I detect click event and differ it from move?


Here's another solution that is very simple and doesn't require you to worry about the finger being moved. If you are basing a click as simply the distance moved then how can you differentiate a click and a long click.

You could put more smarts into this and include the distance moved, but i'm yet to come across an instance when the distance a user can move in 200 milliseconds should constitute a move as opposed to a click.

setOnTouchListener(new OnTouchListener() {
    private static final int MAX_CLICK_DURATION = 200;
    private long startClickTime;

    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN: {
                startClickTime = Calendar.getInstance().getTimeInMillis();
            case MotionEvent.ACTION_UP: {
                long clickDuration = Calendar.getInstance().getTimeInMillis() - startClickTime;
                if(clickDuration < MAX_CLICK_DURATION) {
                    //click event has occurred
        return true;