我有一个带有OnClickListener的Button。为了便于说明,请考虑一个显示模态对话框的按钮:
public class SomeActivity ... {
protected void onCreate(Bundle state) {
super.onCreate(state);
findViewById(R.id.ok_button).setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
// This should block input
new AlertDialog.Builder(SomeActivity.this)
.setCancelable(true)
.show();
}
});
}
在正常使用情况下,会出现警告对话框并阻止进一步输入。用户必须先关闭对话框才能再次点按该按钮。
但有时按钮的OnClickListener会在对话框出现之前调用两次。您可以通过快速点击按钮轻松复制此内容。我通常必须在它发生之前尝试几次,但迟早我会在对话框阻止输入之前触发多次onClick(...)调用。
我在Motorola Droid手机的Android 2.1中看到了这种行为。我们在市场上收到了4份崩溃报告,表明这种情况偶尔发生在人们面前。
根据OnClickListeners的功能,这会导致各种各样的破坏。我们怎样才能保证阻塞对话框在第一次点击后实际阻止输入?
答案 0 :(得分:17)
Romain Guy确认这确实是Android中的一个错误:“仅当用户设法在<125ms内按下按钮两次时才会发生这种情况。我相信我们已经修复了Froyo中可能存在的错误。”
我们将使用“玻璃窗格”模式来解决旧操作系统上的错误。也就是说,我们将以隐形视图覆盖屏幕。在第一次点击事件之后,我们将使视图“可见”,以便拦截后续触摸事件。
仅仅在一个按钮上阻止进一步的事件是不够的。您需要阻止整个活动的所有后续事件,直到对话框被解除,活动恢复等,此时您再次使玻璃窗格“不可见”。
如果这不起作用,我们将不得不忍受这种情况,并且更好地容忍意外的额外事件。
答案 1 :(得分:9)
感谢您尝试,mdma,但这是一个平台问题,而不是我们的代码问题。更糟糕的是,它显然不是一个可以在用户代码中解决的问题(它需要触摸屏驱动程序中未传递的细节)。此外,您的代码示例并不像您认为的那样。 show()不会立即显示对话框。它会在事件队列的末尾添加一条消息,最终显示该对话框。在onClick()返回后,等待执行的队列中可能已有更多触摸事件。
我不确定为什么人们会投票回答。