2010-05-22 194 views
10

我有一個帶有OnClickListener的按鈕。爲了說明的目的,考慮一個按鈕,顯示模態對話框:處理按鈕上的快速點擊

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

您是否嘗試在onClick()外部創建AlertDialog,並在onClick()中調用show()? – jfpoilpret 2010-05-22 00:42:50

回答

17

Romain Guy證實這確實是Android中的一個錯誤:「只有當用戶在< 125ms內按下按鈕兩次時纔會發生,我相信我們在Froyo修復了這個可能的錯誤。

我們將使用「玻璃窗格」模式來解決舊操作系統上的錯誤。也就是說,我們將以不可見的視角覆蓋屏幕。在第一次點擊事件之後,我們將使視圖「可見」,以便攔截後續的觸摸事件。

僅防止一個按鈕上的事件是不夠的。您需要阻止整個活動的所有後續活動,直到對話被解除,活動恢復等等,此時您再次使玻璃窗格「不可見」。

如果這不起作用,我們只需要忍受這一點,並更好地容忍意外的額外事件。

+0

哇...你是鮑勃李? – 2010-05-23 22:27:01

+0

我想這取決於誰是「鮑勃李」。 :-)我不認識Bob Lee的其他程序員。 :-) – 2010-05-24 17:59:09

+1

鮑勃和我正在做一些與鮑勃上面描述的非常相似的東西。主要的區別是我們的「玻璃窗格」不是實際的視圖。相反,我們所有的活動都擴展了一個共同的基礎活動,並且我們所有的對話都擴展了一個基礎對話框。由於我們有這些基類,我們可以在每個基類中引入一個布爾標誌。該標誌表示我們是否接受或阻止輸入。 在每個這些基類中,我們重寫dispatchTouchEvent。根據國旗,我們可以簡單地返回真實,攔截和阻止事件。這種方法似乎有效。 – 2010-05-25 14:22:38

9

感謝您試用mdma,但這是一個平臺問題,而不是我們的代碼問題。更糟糕的是,這顯然不是一個可以在用戶代碼中解決的問題(它需要來自觸摸屏驅動程序的未傳遞的細節)。此外,你的代碼示例不會做你認爲它的作用。 show()不會立即顯示對話框。它在事件隊列的最後添加一條消息,最終顯示對話框。在onClick()返回後,更多的觸摸事件可能已經在隊列中等待執行。

我不確定爲什麼人們投票答案。

+0

嗨,我刪除了我的答案。但我不知道如何確定您是否處於兩州之間 - 在處理點擊和顯示對話之間,然後忽略進一步的點擊之間不可能。 – mdma 2010-05-25 14:46:40