Подтвердить что ты не робот

Как предотвратить быстрый двойной щелчок по кнопке

Я рассмотрел ответы здесь - Android Предотвращение двойного нажатия на кнопку и реализовано решение qezt вроде, и я пробовал setEnabled(false) как это -

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 

        }
    });

Ни одна из них не работает против быстрых двойных щелчков.

Примечание. После завершения обработки я не устанавливаю doneButton.setEnabled(true). Я просто заканчиваю() активность, поэтому нет необходимости слишком быстро активировать кнопку.

4b9b3361

Ответ 1

Я делаю так, как будто это работает очень хорошо.

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);

    }

}

Ответ 2

Я использую такую ​​функцию в слушателе кнопки:

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;
}

Ответ 3

Вероятно, не самый эффективный, но минимальный инверсионный:

...
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);
    }
}

Ответ 4

Вы можете использовать этот метод. Используя задержку по почте, вы можете позаботиться о событиях с двойным щелчком.

void debounceEffectForClick (просмотр) {

view.setClickable(false);

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

    }
}, 500);

}

Ответ 5

Ответ Суру сработал у меня, спасибо!

Я хотел бы добавить следующий ответ для тех, кто использует https://github.com/balysv/material-ripple/blob/master/library/src/main/java/com/balysv/materialripple/MaterialRippleLayout.java и сталкивается с этой проблемой -

app:mrl_rippleDelayClick истинно по умолчанию. Это означает, что onClick будет выполняться только после того, как он закончит показывать пульсацию. Следовательно, setEnabled(false) внутри onClick будет выполняться после задержки, потому что рябь не выполняется, и в этот период вы можете дважды щелкнуть представление.

Установите app:mrl_rippleDelayClick="false", чтобы исправить это. Это означает, что вызов onClick произойдет, как только щелкнет вид, вместо того, чтобы ждать, пока рябь не закончится.

Ответ 6

попробуйте установить yourbutton.setClickable(false) например:

onclick(){
yourbutton.setClickable(false) ;
ButtonLogic();
}

ButtonLogic(){
//your button logic
yourbutton.setClickable(true);
}

Ответ 7

Решение Qezt уже в порядке. Но если вы хотите предотвратить супер быстрый двойной щелчок, то вы просто уменьшаете порог

    // half a second
    if (SystemClock.elapsedRealtime() - doneButtonClickTime < 500) {
        return;
    }

    // or 100ms (1/10 of second)
    if (SystemClock.elapsedRealtime() - doneButtonClickTime < 100) {
        return;
    }

Ответ 8

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());
        }
    }

Я сохранил метод выше в статическом файле, и я вызову этот метод для всех кнопок buttonclick, подобных этому

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

Ответ 9

Короткая версия Kotlin:

private var lastClickTime: Long = 0

//in click listener
if (SystemClock.elapsedRealtime() - lastClickTime < 1000) {
    return
}
lastClickTime = SystemClock.elapsedRealtime()

Ответ 10

Установите launchMode действия в манифесте как singleTop

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