代码之家  ›  专栏  ›  技术社区  ›  Eric Burke

快速点击按钮

  •  10
  • Eric Burke  · 技术社区  · 15 年前

    我有一个按钮,上面有一个吸盘。为了便于说明,请考虑一个显示模式对话框的按钮:

    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(…)调用。

    我在摩托罗拉Droid手机上的Android2.1中看到了这种行为。我们在市场上收到了4份车祸报告,表明这偶尔会发生在人们身上。

    根据我们的同谋所做的,这会造成各种各样的破坏。我们如何保证阻塞对话框实际上在第一次点击后阻塞输入?

    2 回复  |  直到 10 年前
        1
  •  17
  •   Bob Lee    15 年前

    罗曼·盖伊证实这确实是安卓系统中的一个漏洞:“只有用户在125ms内两次按下按钮,才会发生这种情况。我相信我们修复了Froyo中可能出现的错误。”

    我们将使用“玻璃窗格”模式来解决旧操作系统上的错误。也就是说,我们将用看不见的视图覆盖屏幕。在第一次单击事件之后,我们将使视图“可见”,以便它截获随后的触摸事件。

    只按一个按钮就足以阻止进一步的事件发生。您需要阻止整个活动的所有后续事件,直到对话框被取消、活动被恢复等,此时您使玻璃窗格再次“不可见”。

    如果这不起作用,我们只能忍受这种情况,更好地容忍意外的额外事件。

        2
  •  9
  •   Bob Lee    15 年前

    感谢您的尝试,MDMA,但这是一个平台问题,而不是我们的代码问题。更糟糕的是,这显然不是一个可以在用户代码中解决的问题(它需要来自触摸屏驱动程序的细节,而这些细节并没有被传递出去)。而且,您的代码示例并没有像您认为的那样做。show()不会立即显示对话框。它在事件队列的末尾添加一条消息,最终显示对话框。在onclick()返回后,队列中可能已经有更多的触摸事件等待执行。

    我不知道为什么人们会投票决定那个答案。