I have a problem with my app that if the user clicks the button multiple times quickly, then multiple events are generated before even my dialog holding the button disappear
Here's something that will work with any event, not just clicks. It will also deliver the last event even if it's part of a series of rapid events (like rx debounce).
class Debouncer(timeout: Long, unit: TimeUnit, fn: () -> Unit) {
private val timeoutMillis = unit.toMillis(timeout)
private var lastSpamMillis = 0L
private val handler = Handler()
private val runnable = Runnable {
fn()
}
fun spam() {
if (SystemClock.uptimeMillis() - lastSpamMillis < timeoutMillis) {
handler.removeCallbacks(runnable)
}
handler.postDelayed(runnable, timeoutMillis)
lastSpamMillis = SystemClock.uptimeMillis()
}
}
// example
view.addOnClickListener.setOnClickListener(object: View.OnClickListener {
val debouncer = Debouncer(1, TimeUnit.SECONDS, {
showSomething()
})
override fun onClick(v: View?) {
debouncer.spam()
}
})
1) Construct Debouncer in a field of the listener but outside of the callback function, configured with timeout and the callback fn that you want to throttle.
2) Call your Debouncer's spam method in the listener's callback function.