Detect touch press vs long press vs movement? Detect touch press vs long press vs movement? android android

Detect touch press vs long press vs movement?


This code can distinguish between click and movement (drag, scroll). In onTouchEvent set a flag isOnClick, and initial X, Y coordinates on ACTION_DOWN. Clear the flag on ACTION_MOVE (minding that unintentional movement is often detected which can be solved with a THRESHOLD const).

private float mDownX;private float mDownY;private final float SCROLL_THRESHOLD = 10;private boolean isOnClick;@Overridepublic boolean onTouchEvent(MotionEvent ev) {    switch (ev.getAction() & MotionEvent.ACTION_MASK) {        case MotionEvent.ACTION_DOWN:            mDownX = ev.getX();            mDownY = ev.getY();            isOnClick = true;            break;        case MotionEvent.ACTION_CANCEL:        case MotionEvent.ACTION_UP:            if (isOnClick) {                Log.i(LOG_TAG, "onClick ");                //TODO onClick code            }            break;        case MotionEvent.ACTION_MOVE:            if (isOnClick && (Math.abs(mDownX - ev.getX()) > SCROLL_THRESHOLD || Math.abs(mDownY - ev.getY()) > SCROLL_THRESHOLD)) {                Log.i(LOG_TAG, "movement detected");                isOnClick = false;            }            break;        default:            break;    }    return true;}

For LongPress as suggested above, GestureDetector is the way to go. Check this Q&A:

Detecting a long press with Android


From the Android Docs -

onLongClick()

From View.OnLongClickListener. This is called when the user either touches and holds the item (when in touch mode), or focuses upon the item with the navigation-keys or trackball and presses and holds the suitable "enter" key or presses and holds down on the trackball (for one second).

onTouch()

From View.OnTouchListener. This is called when the user performs an action qualified as a touch event, including a press, a release, or any movement gesture on the screen (within the bounds of the item).

As for the "moving happens even when I touch" I would set a delta and make sure the View has been moved by at least the delta before kicking in the movement code. If it hasn't been, kick off the touch code.


I discovered this after a lot of experimentation.

In the initialisation of your activity:

setOnLongClickListener(new View.OnLongClickListener() {  public boolean onLongClick(View view) {    activity.openContextMenu(view);      return true;  // avoid extra click events  }});setOnTouch(new View.OnTouchListener(){  public boolean onTouch(View v, MotionEvent e){    switch(e.getAction & MotionEvent.ACTION_MASK){      // do drag/gesture processing.     }    // you MUST return false for ACTION_DOWN and ACTION_UP, for long click to work    // you can return true for ACTION_MOVEs that you consume.     // DOWN/UP are needed by the long click timer.    // if you want, you can consume the UP if you have made a drag - so that after     // a long drag, no long-click is generated.    return false;  }});setLongClickable(true);