1

I'm using a surfaceview where I just need to identify Up/Down finger swipes. I found this useful: How to handle right to left swipe gestures

However, I also want a given function to be called, say Foo(), whenever the user clicks on the surfaceview (just a single click). This is simple, but got really complicated when I added the gestures swipe thing.

Does anyone know how to do both: single touch events, and UP/Down finger swipes?

Here is what I tried:

  • Inside OnSwipeTouchListener:

    public boolean onTouch(View v, MotionEvent event) {
        Foo();
        return gestureDetector.onTouchEvent(event);
    }
    

    But that resulted in calling Foo() from the moment the user starts the gesture, until the finger is released off the screen (hundreds of times).

  • I also tried discarding this OnSwipeTouchListener class and using onTouchEvent() inside the surface view itself. This worked for single touch events; however, I couldn't detect UP/Down swipes.

     if (event.getAction() == MotionEvent.ACTION_DOWN) {
          mDownY = event.getY();
     }
     else if (event.getAction() == MotionEvent.ACTION_UP) {
        // This code was never called!!
     }
    
Community
  • 1
  • 1
Hajjat
  • 300
  • 2
  • 9

1 Answers1

3

This might help.

1) Have your Activity implement GestureDetector.OnGestureListener.

2) Add a line like gDetector = new GestureDetector( getBaseContext(), this ); in the Activity's onCreate().

3) Override some/all of the six methods belonging to the GestureDetector:

@Override
public boolean onDown(MotionEvent arg0) {
    return false;
}
@Override
public boolean onFling(MotionEvent start, MotionEvent finish, float xVelocity, float yVelocity) {
    if (start.getRawY() < finish.getRawY()) {
        Log.d( TAG, "Swiped down!" );
    } else {
        Log.d( TAG, "Swiped up!" );
    }
    return true;
}
@Override
public void onLongPress(MotionEvent arg0) {
}
@Override
public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2, float arg3) {
    return false;
}
@Override
public void onShowPress(MotionEvent arg0) {
}
@Override
public boolean onSingleTapUp(MotionEvent arg0) {
    Log.d( TAG, "Just tapped at " + arg0.getRawX() + "," + arg0.getRawY() + "!" );
    return false;
}

For your purposes, it sounds like you only need to have to fill in onFling and onSingleTapUp, so that's all I did here.

4) Override onTouchEvent:

@Override
public boolean onTouchEvent(MotionEvent me) {
    return gDetector.onTouchEvent(me);
}

(4) is very important! Otherwise the gesture detector will not fire!

This is explained more here and here; I just took and simplified a smidge.

ETA: First link is from androidsnippets.com (can't tell who the author is), and the content of that link itself is adapted from anddev.org, original author "Danuubz". The fix for the deprecated constructor (already incorporated above) comes from a user "rurussell00" on androidsnippets.com. The second link comes from William J. Francis.

Ken
  • 215
  • 1
  • 2
  • 11