MotionEvent.ACTION_DOWN in Android is too sensitive. This event is received even if the screen is simply touched for a moment

14,558

Solution 1

You can try doing it in ACTION_MOVE or ACTION_UP - if you need it to be done exclusively on swipe down gesture, this should help, introduce four global floats: x, y, x1, y1, then in ACTION_DOWN:

x = event.getX();
y = event.getY();

ACTION_MOVE or ACTION_UP:

x1 = event.getX();
y1 = event.getY();

and then in ACTION_UP:

if (y1 > y) {        //pointer moved down (y = 0 is at the top of the screen)
    startSyncData(); 
}

Solution 2

Its not that easy. It works properly since you are catching MotionEvent.ACTION_DOWN. It doesn't mean a gesture like swipe down it means that user touched the screen (finger down, the touch or gesture just started). Now you need to catch MotionEvent.ACTION_UP (finger up, gesture or touch ends here) and decide if there was a gesture you need. http://developer.android.com/training/gestures/detector.html
http://developer.android.com/training/gestures/index.html

Solution 3

MotionEvent.ACTION_MOVE repeatedly gets called. So if you want startSyncData() to run after moving a certain distance, calculate how much you want the user to move before running the method.

The key is that ACTION_DOWN is not a downwards movement on the screen, but it means the user pressed down onto the screen.

homePageTableLayout.setOnTouchListener(new View.OnTouchListener() {
        public boolean onTouch(View view, MotionEvent event) {
            if ((event.getAction() == MotionEvent.ACTION_DOWN)) {
                startFlg = 1;
            } else if ((event.getAction() == MotionEvent.ACTION_MOVE)) {
                if (startFlg==1){
                    // Calculate distance moved by using event.getRawX() and event.getRawX() and THEN run your method
                    startSyncData();
                }
            }
            return true;
        }
    });
Share:
14,558

Related videos on Youtube

Umang Mathur
Author by

Umang Mathur

Software Engineer

Updated on June 09, 2022

Comments

  • Umang Mathur
    Umang Mathur about 2 years

    I have a layout(A table layout). Whenever the user performs a "down" gesture, a specific function needs to be called. However,the ontouchlistener captures the event immediately instead of waiting until the user performs a proper "pull down" gesture.

    My code is :

    homePageTableLayout.setOnTouchListener(new View.OnTouchListener() {
                public boolean onTouch(View view, MotionEvent event) {
                    if ((event.getAction() == MotionEvent.ACTION_DOWN)) {
                        startSyncData();
                    }
                    return true;
                }
            });
    

    Currently, what's happening is that the startSyncData() function gets called immediately. The end result should be somewhat similar to the commonly used "pulltorefresh" library for android but in this usecase, I don't have to update the view. I just have to post some data to the server. I can't use the "pulltorefresh" library because it does not support "pulling" a tablelayout. I tried putting the tablelayout inside a scrollview but that only spoiled the UI.

    • Han
      Han about 9 years
      Add some more conditions within ACTION_DOWN to specify when you wish the startSyncData() to run.