Avoid button multiple rapid clicks

前端 未结 20 1460
猫巷女王i
猫巷女王i 2020-11-28 02:55

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

20条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-11-28 03:16

    A Handler based throttler from Signal App.

    import android.os.Handler;
    import android.support.annotation.NonNull;
    
    /**
     * A class that will throttle the number of runnables executed to be at most once every specified
     * interval.
     *
     * Useful for performing actions in response to rapid user input where you want to take action on
     * the initial input but prevent follow-up spam.
     *
     * This is different from a Debouncer in that it will run the first runnable immediately
     * instead of waiting for input to die down.
     *
     * See http://rxmarbles.com/#throttle
     */
    public final class Throttler {
    
        private static final int WHAT = 8675309;
    
        private final Handler handler;
        private final long    thresholdMs;
    
        /**
         * @param thresholdMs Only one runnable will be executed via {@link #publish} every
         *                  {@code thresholdMs} milliseconds.
         */
        public Throttler(long thresholdMs) {
            this.handler     = new Handler();
            this.thresholdMs = thresholdMs;
        }
    
        public void publish(@NonNull Runnable runnable) {
            if (handler.hasMessages(WHAT)) {
                return;
            }
    
            runnable.run();
            handler.sendMessageDelayed(handler.obtainMessage(WHAT), thresholdMs);
        }
    
        public void clear() {
            handler.removeCallbacksAndMessages(null);
        }
    }
    

    Example usage:

    throttler.publish(() -> Log.d("TAG", "Example"));
    

    Example usage in an OnClickListener:

    view.setOnClickListener(v -> throttler.publish(() -> Log.d("TAG", "Example")));
    

    Example Kt usage:

    view.setOnClickListener {
        throttler.publish {
            Log.d("TAG", "Example")
        }
    }
    

    Or with an extension:

    fun View.setThrottledOnClickListener(throttler: Throttler, function: () -> Unit) {
        throttler.publish(function)
    }
    

    Then example usage:

    view.setThrottledOnClickListener(throttler) {
        Log.d("TAG", "Example")
    }
    

提交回复
热议问题