How to prevent a quick double click on a button

I reviewed the answers here - Android Preventing a double click on a button and implemented a qezt solution like, and I tried setEnabled(false) like this -

 doneButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // mis-clicking prevention, using threshold of 1 second if (SystemClock.elapsedRealtime() - doneButtonClickTime < 1000){ return; } //store time of button click doneButtonClickTime = SystemClock.elapsedRealtime(); doneButton.setEnabled(false); //do actual work } }); 

None of them work against quick double clicks.

Note. After processing is complete, I do not set doneButton.setEnabled(true) . I just end () the activity, so there is no need to activate the button too quickly.

+10
android
source share
10 answers

I make it work very well.

 public abstract class OnOneOffClickListener implements View.OnClickListener { private static final long MIN_CLICK_INTERVAL=600; private long mLastClickTime; public static boolean isViewClicked = false; public abstract void onSingleClick(View v); @Override public final void onClick(View v) { long currentClickTime=SystemClock.uptimeMillis(); long elapsedTime=currentClickTime-mLastClickTime; mLastClickTime=currentClickTime; if(elapsedTime<=MIN_CLICK_INTERVAL) return; if(!isViewClicked){ isViewClicked = true; startTimer(); } else { return; } onSingleClick(v); } /** * This method delays simultaneous touch events of multiple views. */ private void startTimer() { Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { isViewClicked = false; } }, 600); } } 
+12
source share

I use this function in a button listener:

 public static long lastClickTime = 0; public static final long DOUBLE_CLICK_TIME_DELTA = 500; public static boolean isDoubleClick(){ long clickTime = System.currentTimeMillis(); if(clickTime - lastClickTime < DOUBLE_CLICK_TIME_DELTA){ lastClickTime = clickTime; return true; } lastClickTime = clickTime; return false; } 
+5
source share

Probably not the most efficient, but minimal inversion:

 ... onClick(View v) { MultiClickPreventer.preventMultiClick(v); //your op here } ... public class MultiClickPreventer { private static final long DELAY_IN_MS = 500; public static void preventMultiClick(final View view) { if (!view.isClickable()) { return; } view.setClickable(false); view.postDelayed(new Runnable() { @Override public void run() { view.setClickable(true); } }, DELAY_IN_MS); } } 
+3
source share

You can use this method. Using mail delay, you can take care of events with a double click.

void debounceEffectForClick (view) {

 view.setClickable(false); view.postDelayed(new Runnable() { @Override public void run() { view.setClickable(true); } }, 500); 

}

+2
source share

Suru's answer worked for me, thanks!

I would like to add the following answer for those who use https://github.com/balysv/material-ripple/blob/master/library/src/main/java/com/balysv/materialripple/MaterialRippleLayout.java and come across this the problem is

app:mrl_rippleDelayClick true by default. This means that onClick will only be executed after it finishes showing ripple. Therefore, setEnabled(false) inside onClick will execute after the delay because ripples fail, and during this period you can double-click the view.

Set app:mrl_rippleDelayClick="false" to fix this. This means that the onClick call will happen as soon as the view clicks, instead of waiting until the ripples end.

+1
source share

try setting yourbutton.setClickable (false) for example:

 onclick(){ yourbutton.setClickable(false) ; ButtonLogic(); } ButtonLogic(){ //your button logic yourbutton.setClickable(true); } 
0
source share

Qezt's solution is already in order. But if you want to prevent a super fast double click, then you simply lower the threshold

  // half a second if (SystemClock.elapsedRealtime() - doneButtonClickTime < 500) { return; } // or 100ms (1/10 of second) if (SystemClock.elapsedRealtime() - doneButtonClickTime < 100) { return; } 
0
source share
 public static void disablefor1sec(final View v) { try { v.setEnabled(false); v.setAlpha((float) 0.5); v.postDelayed(new Runnable() { @Override public void run() { try { v.setEnabled(true); v.setAlpha((float) 1.0); } catch (Exception e) { Log.d("disablefor1sec", " Exception while un hiding the view : " + e.getMessage()); } } }, 1000); } catch (Exception e) { Log.d("disablefor1sec", " Exception while hiding the view : " + e.getMessage()); } } 

I saved the method above in a static file and I will call this method for all buttonclick buttons like this

  button_or_textview.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { StaticFile.disablefor1sec(button_or_textview); // Do Somthing. } }); 
0
source share

Short version of Kotlin:

 private var lastClickTime: Long = 0 //in click listener if (SystemClock.elapsedRealtime() - lastClickTime < 1000) { return } lastClickTime = SystemClock.elapsedRealtime() 
0
source share

Set launchMode actions in the manifest as singleTop

  <activity android:name="com.example.MainActivity" android:screenOrientation="portrait" android:launchMode="singleTop"/> 
0
source share

All Articles