Question

I want to implement a listener for my view. I want to detect a simple click a double tap and a long press and that is all. Here is the code I wrote (pertinent parts only):

public class BoardView extends View implements OnGestureListener, OnDoubleTapListener{

    //My functions and code. 

@Override 
public boolean onTouchEvent(MotionEvent event){ 
    Toast t = Toast.makeText(this.getContext(), "I'm touched", Toast.LENGTH_SHORT);
    t.show();
    System.err.println("On Touch");
    return super.onTouchEvent(event);
}

public void onLongPress(MotionEvent event) {
    Toast t = Toast.makeText(this.getContext(), "I get it, stop touching me!!!", Toast.LENGTH_SHORT);
    t.show();       
    System.err.println("Long Press");
    //Log.d(DEBUG_TAG, "onLongPress: " + event.toString()); 
}

@Override
public void onGesture(GestureOverlayView overlay, MotionEvent event) {

}

@Override
public void onGestureCancelled(GestureOverlayView overlay, MotionEvent event) {

}

@Override
public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) {


}

@Override
public void onGestureStarted(GestureOverlayView overlay, MotionEvent event) {
    // TODO Auto-generated method stub

}

@Override
public boolean onDoubleTapEvent(MotionEvent e) {
    return false;
}

@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
    // TODO Auto-generated method stub
    return false;
}

@Override
public boolean onDoubleTap(MotionEvent e) {
    Toast t = Toast.makeText(this.getContext(), "Soy double the joy", Toast.LENGTH_SHORT);
    t.show();
    System.err.println("Double Tap");
    return true;
}
}

I detect the touch perfectly but not the double tap or the long press.... what am I doing wrong?

EDIT: Following one of the answers I wrote the following code:

private class Gestures extends SimpleOnGestureListener{

    public Gestures(){          
    }

    public void onTouchEvent(MotionEvent event){
        System.err.println("Touch Even gestures");
    }
     @Override
        public void onLongPress(MotionEvent event) {
            System.err.println("Long Press");
        }

     @Override
        public boolean onDoubleTap(MotionEvent event) {
         System.err.println("Double Tap");
            return true;
        }

}

Gestures gdetector = new Gestures();

This is before my BoardView constructor. Then as I understand I should have done:

@Override 
public boolean onTouchEvent(MotionEvent event){     
gdetector.onTouchEvent(event);
    return super.onTouchEvent(event);
}

However I only got the simple touch detected....

Was it helpful?

Solution

You should simply extend GestureDetector.SimpleOnGestureListener in some inner class of your view and override methods you want(double tap, long press etc.) and you can handle these gestures with gesture detector containing this listener.

Example view could look like this:

public class GestureView extends View
{
    private GestureDetector mGestureDetector;

    //only one constructor for shorter code, in final code all should be presented
    public GestureView(Context context, AttributeSet attrs)
    {
        super(context, attrs);

        final MyGestureListener myGestureListener = new MyGestureListener();
        mGestureDetector = new GestureDetector(context, myGestureListener);
        mGestureDetector.setOnDoubleTapListener(myGestureListener);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        return mGestureDetector.onTouchEvent(event) || super.onTouchEvent(event);
    }

    private class MyGestureListener extends GestureDetector.SimpleOnGestureListener
    {
        @Override
        public boolean onDown(MotionEvent event)
        {
            return true;
        }

        @Override
        public void onLongPress(MotionEvent e)
        {
            //your code here
        }

        @Override
        public boolean onDoubleTap(MotionEvent e)
        {
            //your code here return true if event handled
            return super.onDoubleTap(e);
        }

        //this can be taken as click
        @Override
        public boolean onSingleTapConfirmed(MotionEvent e)
        {
            //your code here return true if event handled
            return super.onSingleTapConfirmed(e);
        }
    }
}

If you want just to add gesture detector to some other view, you can simply call its onTouch method from onTouchListener like

view.setOnTouchListener(new View.OnTouchListener()
{
    @Override
    public boolean onTouch(View v, MotionEvent event)
    {
        return gestureDetector.onTouchEvent(event);
    }
});

OTHER TIPS

Instead of writing a custom view, what don't you look into View.setOnLongClickListener() and View.setOnClickListener().

http://developer.android.com/reference/android/view/View.html

LongClickListener is definitely what you want to listen for long clicks, and with some state tracking variables a normal onClickListener can handle a double tap.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top