Android detecting double tap without single tap first

steveh picture steveh · Feb 6, 2013 · Viewed 11.7k times · Source

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

Answer

andr picture andr · Feb 6, 2013

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.