问题
A common problem in android apps for me seems to be, that click events can be triggered multiple times, when they should not.
I am using Butterknife - consider the following example
@OnClick(R.id.button_foto_aufnehmen)
protected void takePicture() {
m_camera.takePicture();
}
with a camera app with some layout containing
<SurfaceView
android:id="@+id/surface_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
...
<ImageButton
android:id="@+id/button_foto_aufnehmen"
.../>
Now it should not be possible to click the button again, until at least after the onPictureTaken
callback has completed - or even later.
Another example would be
I really don't want to manually introduce a boolean flag every time this comes up. I'd think of something like an annotation that allows me to specify an event that resets a boolean which is generated automatically. Anything but boilerplate code please.
So what is the best practice here (particularly keeping in mind the usage of butter knife)?
回答1:
I have faced this situation before. Basically I ended up implementing my own CustomClickListener and setting a threshold of a specific time interval (for instance, 1000ms) before allowing firing the trigger. Basically when you click the button and trigger the listener, it will check if the trigger was executed in the past amount of time you defined, and if not it will trigger it.
public class CustomClickListener implements View.OnClickListener {
protected int defaultInterval;
private long lastTimeClicked = 0;
public CustomClickListener() {
this(1000);
}
public CustomClickListener(int minInterval) {
this.defaultInterval = minInterval;
}
@Override
public void onClick(View v) {
if (SystemClock.elapsedRealtime() - lastTimeClicked < defaultInterval) {
return;
}
lastTimeClicked = SystemClock.elapsedRealtime();
performClick(v);
}
public abstract void performClick(View v);
}
And in your class, you can do the following without jeopardizing your implementation (normal code)
myButton = (Button) findViewById(R.id.my_button);
myButton.setOnClickListener(new CustomClickListener() {
@Override
public void performClick(View view) {
// do stuff
}
});
or by using a ButterKnife implentation (I have not tested yet since I dont have Android Studio available within my grasp at the moment, so if it works let me know) :
@Bind(R.id.my_button)
Button myButton;
@OnClick(R.id.button)
@Override
public void performClick(View view) {
// do stuff
}
Regards,
回答2:
The above solution is very good. But it will become even better when using the power of Kotlin
1) Create the SafeClikc Listener
class SafeClickListener(
private var defaultInterval: Int = 1000,
private val onSafeCLick: (View) -> Unit
) : View.OnClickListener {
private var lastTimeClicked: Long = 0
override fun onClick(v: View) {
if (SystemClock.elapsedRealtime() - lastTimeClicked < defaultInterval) {
return
}
lastTimeClicked = SystemClock.elapsedRealtime()
onSafeCLick(v)
}
}
2) Add extension function to make it works with any view, this will create a new SafeClickListener and delegate the work to it
fun View.setSafeOnClickListener(onSafeClick: (View) -> Unit) {
val safeClickListener = SafeClickListener {
onSafeClick(it)
}
setOnClickListener(safeClickListener)
}
3) Now it is very easy to use it
settingsButton.setSafeOnClickListener {
showSettingsScreen()
}
Happy Kotlin ;)
来源:https://stackoverflow.com/questions/38503188/button-click-triggered-multiple-times