如何防止双击按钮重复操作?

How to prevent repeating actions on double click on the button?

这是我在 onClick() 中的操作。问题是,如果我按两次按钮,新的 activity 将被打开两次。我尝试使用 setEnabled() 和 setClickable(),但它不起作用。它仍然显示不止一个 activity

button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(getActivity(), 
CalendarActivity.class);
            intent.putExtra("day", 16);
            intent.putExtra("month", 12);
            intent.putExtra("year", 1996);
            startActivityForResult(intent, CALENDAR_ACTIVITY_CODE);
        }
    });

尝试在他第一次被点击后禁止按钮被点击:

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    //add this line
    button.setClickable(false);
        Intent intent = new Intent(getActivity(), CalendarActivity.class);
        intent.putExtra("day", 16);
        intent.putExtra("month", 12);
        intent.putExtra("year", 1996);
        startActivityForResult(intent, CALENDAR_ACTIVITY_CODE);
    }
});

如果这对您没有帮助,您可以转到清单中的 activity 并添加:

android:launchMode = "singleTop"

这实际上是一个非常复杂的问题。问题的根源在于 UI 事件(例如单击按钮)导致 消息 成为消息队列末尾的 "posted"。如果您足够快,可以在处理第一条消息之前将其中的许多消息发布到消息队列。

这意味着即使禁用 onClick() 方法中的按钮也无法真正解决问题(因为在处理第一条消息之前禁用不会 "happen",但您可能已经消息队列中有另外三个重复的消息在等待)。

最好的办法是跟踪某种布尔标志,每次检查标志 inside onClick():

private boolean firstClick = true;
button.setOnClickListener(v -> {
    if (firstClick) {
        firstClick = false;
        // do your stuff
    }
});

当然,无论何时您想要重新启用按钮点击,您都必须记住将 firstClick 重置为 true。

要解决此问题,您可以使用 Jake Wharton Rxbinding 库,它允许您将点击事件转换为流。

您可以添加节流事件,这有助于从指定时间停止事件

RxView.clicks(button).throttleFirst(2, TimeUnit.SECONDS)
                .observeOn(AndroidSchedulers.mainThread()).
                        subscribe(new Consumer<Object>() {
                            @Override
                            public void accept(Object o) {
                                Toast.makeText(getApplicationContext(), "Avoid multiple clicks using throttleFirst", Toast.LENGTH_SHORT).show();
                            }
                        });