Button Click triggered multiple times

无人久伴 提交于 2019-12-13 21:43:01

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!