Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android detecting double tap without single tap first

i would like to detect a double tap BUT without triggering a single tap first. i've tried double click listeners but you always get a onSingleTapUp before the double is detected, which is reasonable i guess. but in my app, i really don't want the single click callback when there is a double click on the way.

i realize no app can predict the future (or i would be really rich) but i was thinking, just launch a timer on the single click and if there is no double click within some time out, then do the single click. but that doesn't seem to work because once i start the timer and the timer is running, the second tap never generates an event. here's my code using an aync task, i also tried it with a timer.

mGD = new GestureDetector(getContext(), new SimpleOnGestureListener() {

            @Override
            public boolean onSingleTapUp(MotionEvent ev) {
                //Log.d("KitView", "onSingleTapUp "+ev.toString());

                class DblTapTask extends AsyncTask<Void, Void, Void> {

                    @Override
                    protected void onPreExecute() {
                        Log.d("KitView", "onPreExecute");
                    }

                    protected Void doInBackground(Void... args) {
                        Log.d("KitView", "doInBackground");
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        return null;
                    }

                    protected void onPostExecute(Void result) {
                        Log.d("KitView", "onPostExecute");
                                            doSigleTapAction();
                        mDblTapTask=null;
                    }
                };

                if(mDblTapTask==null) {
                    Log.d("KitView", "START TASK");
                    mDblTapTask = new DblTapTask();
                    mDblTapTask.execute();
                } else {
                    Log.d("KitView", "TASK RUNNING");
                                    doDoubleTapAction();
                }


                Log.d("KitView", "onSingleTapUp DONE");
                return true;
            }   // end onSingleTapUp

        });     // end new GestureDetector

in this example, i get onSingleTapUp just fine on the first tap. my timeout is 1 sec for testing in the doInBackground so i have lots of time to do the second tap. note that Log.d("KitView", "onSingleTapUp DONE"); runs immediately i do the first tap, so onSingleTapUp is not hanging.

the problem is, taping again within the 1sec does nothing. there is no call to onSingleTapUp until after the sleep has finished and onPostExecute has run. so Log.d("KitView", "TASK RUNNING"); never happens which is where i would detect double click vs. single click of course.

i'm not sure why aynctask is blocking events, any ideas? thanks

like image 997
steveh Avatar asked Feb 06 '13 08:02

steveh


2 Answers

I'm confused on what you're trying to achieve. The double tap method onDoubleTap() isn't called when the single tap occurs. On the other hand, for every double tap there are two associated single tap onSingleTapUp() method calls.

If you want to distinguish them, you can use onSingleTapConfirmed() which is triggered when the gesture detector is sure the tap is single. See reference:

Notified when a single-tap occurs.

Unlike OnGestureListener.onSingleTapUp(MotionEvent), this will only be called after the detector is confident that the user's first tap is not followed by a second tap leading to a double-tap gesture

You can then use this method call in combination with a boolean flag to essentially detect any type of single/double tap.

like image 138
andr Avatar answered Sep 29 '22 17:09

andr


Try out as below :

You can use the GestureDetector. See the following code:

public class MyView extends View {

GestureDetector gestureDetector;

public MyView(Context context, AttributeSet attrs) {
    super(context, attrs);
            // creating new gesture detector
    gestureDetector = new GestureDetector(context, new GestureListener());
}

// skipping measure calculation and drawing

    // delegate the event to the gesture detector
@Override
public boolean onTouchEvent(MotionEvent e) {
    return gestureDetector.onTouchEvent(e);
}


private class GestureListener extends GestureDetector.SimpleOnGestureListener {

    @Override
    public boolean onDown(MotionEvent e) {
        return true;
    }
    // event when double tap occurs
    @Override
    public boolean onDoubleTap(MotionEvent e) {
        Log.d("Double Tap", "Tapped Occured.");
        return true;
    }
}
}

You can override other methods of the listener to get single taps, flinges and so on.

like image 42
GrIsHu Avatar answered Sep 29 '22 15:09

GrIsHu