Why ButterKnife uses a DebouncingOnClickListener for @OnClick methods?
Asked Answered
A

2

13

I was looking at the generated code of ButterKnife, and noticed that for @OnClick annotations it is using a DebouncingOnClickListener, implemented by the library.

What the DebouncingOnClickListener does it to avoid more than one click on any element using that listener on the same frame (to achieve this they use a static flag). You can see the implementation here.

I have tried to find an explanation on why they decided to use this for every on click event managed by the library, but could not find any.

So, why they use that? Why have they decided that every user of ButterKnife need this? Shouldn't be the user who decides to use that or not? Why couple the view binding help it provides with this "feature"? What happens if I want to receive more than one click on the same frame? I couldn't use ButterKnife for click events.

I don't pretend to be offensive, just want an explanation, maybe I am missing something.

A answered 17/10, 2015 at 20:15 Comment(1)
It's an open source library. If it bothers you that much, I'm sure that pull requests would be welcome. If not, you can always fork it.Flocculus
S
8

Why have they decided that every user of ButterKnife need this?

Assume you have a button and a click event on this button launches a new activity. Now what will happen, when user very quickly double taps the button? There is some chance, that the click listener would be fired two times, thus 2 activities would be launched, which you most possibly do not want.

What this DebouncingOnClickListener does is it assures, that no subsequent click listener would be regarded. As soon as the first click happens, subsequent clicks would be disregarded until next frame, when they would be switched on.

When you are performing an action with a view, you are posting an event on the MessageQueue. Now, when first click happens, you are posting an event - launch new activity. And you are immediately posting another event - enable click listener, on the next frame. The second event is guaranteed to happen after the first one, because is has been post()ed to the queue.

What happens if I want to receive more than one click on the same frame?

If it is acceptable for you to receive multiple subsequent click events, than you should use @OnTouch, because you are interested in touch event and not in click events.


Listen to @Piwai's clarification concerning the case at Fragmented Podcast #88 (starting from 38:20).

Stanleigh answered 5/7, 2017 at 12:38 Comment(2)
Default onClickListner should be implemented this way. Shame GoogleBlackleg
Be careful. If you start activity via intent from butterknife's onClick() method, it won't save you from multiple instances lunching. Debounce works only for one frame. New Activity can take longer time to spin up. It is not useless feature, but not a silver bullet either.Jowers
P
1

Long story short, it's to prevent a bug from happening since touch events are async. You can also use the library for binding still but assign regular on click listeners.

This podcast episode covers it pretty well Fragmented 088

Princess answered 5/7, 2017 at 12:6 Comment(2)
What does mean "touch events are async"? Any example?Stanleigh
It means that the touch event is processed off of the main that. So you aren't guaranteed the order things will be processed inPrincess

© 2022 - 2024 — McMap. All rights reserved.