在安卓系统中防止双击按钮的最佳方法是什么?


当前回答

结合Gustavo的答案,我已经在Kotlin中实现了看起来非常干净的扩展:

fun View.setOnSingleClickListener(l: () -> Unit) {
  setOnClickListener { view ->
    l.invoke(view)
      isEnabled = false
      postDelayed({
        isEnabled = true
      }, 600)
  }
}

这是你如何设置这个点击监听器:

yourView.setOnSingleClickListener {
  // Insert your code here
}

其他回答

我更喜欢使用信号量块。它是线程安全的,不仅可以用于按钮。

代码示例很简单:

private UtilsSemaphore buttonSemaphore = new UtilsSemaphore();

public void onClick(View view)
{

    boolean isAllowed = buttonSemaphore.lock();

    if(!isAllowed)
    {
        return;
    }

    final View clickedButton = view;

    clickedButton.setEnabled(false);

    /* some code */

    buttonSemaphore.unlock();
    clickedButton.setEnabled(true);
}


public class UtilsSemaphore {

    public int counter = 0;

    public boolean lock()
    {
        int counterValue = ++counter;
        boolean isAllowed = counterValue < 2;

        if(!isAllowed)
        {
            unlock();
        }

        return isAllowed;
    }

    public void unlock()
    {
        --counter;
    }

}

具有Kotlin扩展功能:

fun View.onSingleClick(action: (v: View) -> Unit) {
    setOnClickListener(object : View.OnClickListener {
        override fun onClick(v: View) {
            isClickable = false
            action(v)
            postDelayed({ isClickable = true }, 700)
        }
    })
}

用法:

button.onSingleClick { myAction() }

这是我的解决方案:

if (waitDouble) {
    waitDouble = false;
    Thread thread = new Thread() {
        @Override
        public void run() {
            try {
                sleep(300);
                if (waitDouble == false) {
                    waitDouble = true;
                    singleClick();  //singleClick
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };
    thread.start();
} else {//DoubleClick
    DoubleClick();
    waitDouble = true;
}

或者另一种解决方案:

public class NoDoubleClickUtils {
    private static long lastClickTime;
    private final static int SPACE_TIME = 500;

    public static void initLastClickTime() {
        lastClickTime = 0;
    }

    public synchronized static boolean isDoubleClick() {
        long currentTime = System.currentTimeMillis();
        boolean isClick2;
        if (currentTime - lastClickTime > SPACE_TIME) {
            isClick2 = false;
        } else {
            isClick2 = true;
        }
        lastClickTime = currentTime;
        return isClick2;
    }
}

在kotlin

button.setOnClickListener { 
    it?.apply { isEnabled = false; postDelayed({ isEnabled = true }, 400) } //400 ms
    //do your work
}

在点击的时候保存最后一次点击的时间可以避免这个问题。

i.e.

private long mLastClickTime = 0;

...

// inside onCreate or so:

findViewById(R.id.button).setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        // mis-clicking prevention, using threshold of 1000 ms
        if (SystemClock.elapsedRealtime() - mLastClickTime < 1000){
            return;
        }
        mLastClickTime = SystemClock.elapsedRealtime();

        // do your magic here
    }
}