Ensure single click on Android (ButterKnife did it right 👌)

Thanos Tsakiridis
ProAndroidDev
Published in
2 min readJul 10, 2020

--

Photo by John Schnobrich on Unsplash

Recently, while I was investigating a weird issue of double network calls, I discovered that the root cause was not some bad network state or my HTTP client, but something much more simple and often overlooked. User double-tapping on a button too quickly…

A few years ago (like a lifetime in Android development) ButterKnife library was extremely popular for Java-based apps to bind views and avoid all the findViewById calls. It also used simple annotations like @OnClick to annotate methods and avoid setting up click listeners, I believe these are pretty known stuff. Now we use Kotlin synthetics (❤️) or View Binding , so ButterKnife got deprecated.

But as I mentioned ButterKnife had among others, this @OnClick annotation and it was hiding a small perk if you check the generated code: DebouncingClickListener

A View.OnClickListener click listener that debounces multiple clicks posted in the same frame. A click on one button disables all buttons for that frame.

What it did, was when you set up a click listener using the annotation, it automatically prevented for you accidental quick double clicks which may lead to weird behavior like the double network calls I was facing 😏 , or double pop up of dialogs, etc. but for all buttons that used this class as click handler! ButterKnife was indeed beautiful!

Of course, we can’t go back, but my idea was to copy and then extend the behavior with the help of Kotlin and extension methods.

First I created a DebouncingOnClickListener that was an exact copy of the original, translated to Kotlin. Then I added an extra parameter intervalMillis that can prevent clicks for a specified time period and not only for that frame.

And then an extension method to add this listener to my views:

I used a default value of 0 for the interval (which is the same as ButterKnife with disabling for one frame) so passing a value for the interval when you set the click listener at the view is totally optional. And the best is, that it will prevent clicks for all views that have this click handler!

And that’s it! No more double clicks! ✌️

--

--