Last active
October 16, 2023 11:43
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} |
Yes, thank you..
Thank you so much for this. took 2 seconds to add to my project.
doesn't work for me..trying to use in a fragment adapter
Worked perfectly for me. Thankyou :')
Could you add a Kotlin version of DoubleClickListener too? Thanks.
kotlin version -
import android.view.View
class DoubleClickListener(
private val doubleClickTimeLimitMills: Long = 1000,
private val callback: Callback
) :
View.OnClickListener {
private var lastClicked: Long = -1L
override fun onClick(v: View?) {
lastClicked = when {
lastClicked == -1L -> {
System.currentTimeMillis()
}
isDoubleClicked() -> {
callback.doubleClicked()
-1L
}
else -> {
System.currentTimeMillis()
}
}
}
private fun getTimeDiff(from: Long, to: Long): Long {
return to - from
}
private fun isDoubleClicked(): Boolean {
return getTimeDiff(
lastClicked,
System.currentTimeMillis()
) <= doubleClickTimeLimitMills
}
interface Callback {
fun doubleClicked()
}
}
Impl -
binding.imageView.setOnClickListener(
DoubleClickListener(
callback = object : DoubleClickListener.Callback {
override fun doubleClicked() {
}
}
)
)
Thanks @sagarnayak for your script :)
Kotlin version, Smaller with an extension function
/**
* Is an onClickListener that handles doubleClickListener
*
* @param doubleClickQualificationTime The time in which the second tap should be done
* in order to qualify as a double click. Time in MS
*/
abstract class DoubleClickListener(
private val doubleClickQualificationTime: Long = 200
) : View.OnClickListener {
private var timestampLastClick = 0L
/***/
override fun onClick(v: View) {
if ((elapsedRealtime() - timestampLastClick) < doubleClickQualificationTime)
onDoubleClick(v)
timestampLastClick = elapsedRealtime();
}
/** When the view is double clicked */
abstract fun onDoubleClick(v: View)
}
/**
* Creates a [DoubleClickListener] and applies it to a view
*/
inline fun View.setOnDoubleClickListener(
crossinline onDoubleClick: (View) -> Unit
) {
setOnClickListener(object : DoubleClickListener() {
override fun onDoubleClick(v: View) {
onDoubleClick(v)
}
})
}
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
}
}
Hi @srix55, is there any way to detect more than 2 taps? Maybe by parameterizing the quantity itself, whether it is 2 or 10.
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 } }
👍
Thanks, @Duna !
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Works perfectly! Thank you.