Skip to content

Instantly share code, notes, and snippets.

@srix55
Last active October 16, 2023 11:43
Show Gist options
  • Save srix55/ec64d2f6a371c80bbbc4 to your computer and use it in GitHub Desktop.
Save srix55/ec64d2f6a371c80bbbc4 to your computer and use it in GitHub Desktop.
Simple double-click listener that can be used like the way OnClickListener is used on a view in Android
import android.os.SystemClock;
import android.view.View;
import android.view.View.OnClickListener;
/**
* A simple double-click listener
* Usage:
* // Scenario 1: Setting double click listener for myView
* myView.setOnClickListener(new DoubleClickListener() {
*
* @Override
* public void onDoubleClick() {
* // double-click code that is executed if the user double-taps
* // within a span of 200ms (default).
* }
* });
*
* // Scenario 2: Setting double click listener for myView, specifying a custom double-click span time
* myView.setOnClickListener(new DoubleClickListener(500) {
*
* @Override
* public void onDoubleClick() {
* // double-click code that is executed if the user double-taps
* // within a span of 500ms (default).
* }
* });
*
* @author Srikanth Venkatesh
* @version 1.0
* @since 2014-09-15
*/
public abstract class DoubleClickListener implements OnClickListener {
// The time in which the second tap should be done in order to qualify as
// a double click
private static final long DEFAULT_QUALIFICATION_SPAN = 200;
private long doubleClickQualificationSpanInMillis;
private long timestampLastClick;
public DoubleClickListener() {
doubleClickQualificationSpanInMillis = DEFAULT_QUALIFICATION_SPAN;
timestampLastClick = 0;
}
public DoubleClickListener(long doubleClickQualificationSpanInMillis) {
this.doubleClickQualificationSpanInMillis = doubleClickQualificationSpanInMillis;
timestampLastClick = 0;
}
@Override
public void onClick(View v) {
if((SystemClock.elapsedRealtime() - timestampLastClick) < doubleClickQualificationSpanInMillis) {
onDoubleClick();
}
timestampLastClick = SystemClock.elapsedRealtime();
}
public abstract void onDoubleClick();
}
@Duna
Copy link

Duna commented Dec 30, 2020

How about detecting both: simple and double clicks?

public abstract static class DoubleClickListener implements View.OnClickListener {
        private static final long DEFAULT_QUALIFICATION_SPAN = 200;
        private long delta;
        private long deltaClick;

        public DoubleClickListener() {
            delta = DEFAULT_QUALIFICATION_SPAN;
            deltaClick = 0;
        }

        @Override
        public void onClick(View v) {
            han.removeCallbacksAndMessages(null);
            han.postDelayed(new Runnable() {
                @Override
                public void run() {
                    onSingleClick();
                }
            }, delta);
            if ((SystemClock.elapsedRealtime() - deltaClick) < delta) {
                han.removeCallbacksAndMessages(null);
                onDoubleClick();
            }
            deltaClick = SystemClock.elapsedRealtime();
        }

        public abstract void onDoubleClick();

        public abstract void onSingleClick();
    }

and for Kotlin lovers 😍

abstract class DoubleClickListener : View.OnClickListener {
        private val delta: Long
        private var deltaClick: Long
        override fun onClick(v: View) {
            han.removeCallbacksAndMessages(null)
            han.postDelayed({ onSingleClick() }, delta)
            if (SystemClock.elapsedRealtime() - deltaClick < delta) {
                han.removeCallbacksAndMessages(null)
                onDoubleClick()
            }
            deltaClick = SystemClock.elapsedRealtime()
        }

        abstract fun onDoubleClick()
        abstract fun onSingleClick()

        companion object {
            private const val DEFAULT_QUALIFICATION_SPAN: Long = 200
        }

        init {
            delta = DEFAULT_QUALIFICATION_SPAN
            deltaClick = 0
        }
    }

@andreadibartolo
Copy link

Hi @srix55, is there any way to detect more than 2 taps? Maybe by parameterizing the quantity itself, whether it is 2 or 10.

@yahyalmh
Copy link

How about detecting both: simple and double clicks?

public abstract static class DoubleClickListener implements View.OnClickListener {
        private static final long DEFAULT_QUALIFICATION_SPAN = 200;
        private long delta;
        private long deltaClick;

        public DoubleClickListener() {
            delta = DEFAULT_QUALIFICATION_SPAN;
            deltaClick = 0;
        }

        @Override
        public void onClick(View v) {
            han.removeCallbacksAndMessages(null);
            han.postDelayed(new Runnable() {
                @Override
                public void run() {
                    onSingleClick();
                }
            }, delta);
            if ((SystemClock.elapsedRealtime() - deltaClick) < delta) {
                han.removeCallbacksAndMessages(null);
                onDoubleClick();
            }
            deltaClick = SystemClock.elapsedRealtime();
        }

        public abstract void onDoubleClick();

        public abstract void onSingleClick();
    }

and for Kotlin lovers

abstract class DoubleClickListener : View.OnClickListener {
        private val delta: Long
        private var deltaClick: Long
        override fun onClick(v: View) {
            han.removeCallbacksAndMessages(null)
            han.postDelayed({ onSingleClick() }, delta)
            if (SystemClock.elapsedRealtime() - deltaClick < delta) {
                han.removeCallbacksAndMessages(null)
                onDoubleClick()
            }
            deltaClick = SystemClock.elapsedRealtime()
        }

        abstract fun onDoubleClick()
        abstract fun onSingleClick()

        companion object {
            private const val DEFAULT_QUALIFICATION_SPAN: Long = 200
        }

        init {
            delta = DEFAULT_QUALIFICATION_SPAN
            deltaClick = 0
        }
    }

👍

@danielandrioli
Copy link

Thanks, @Duna !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment