2012-06-01 60 views
19

按鈕觸發一個只應調用一次的動作。在執行行動前的按鈕被禁用,隱藏在onclick處理程序:Android:防止按鈕(已被禁用)上的多個onClick事件

即使
someButton.setOnClickListener(new OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     someButton.setEnabled(false); 
     someButton.setClickable(false); 
     someButton.setVisibility(View.GONE); 
     performTaskOnce(); 
     } 
    }); 

private void performTaskOnce() { 
    Log.i("myapp", "Performing task"); 
    //Do something nontrivial that takes a few ms (like changing the view hierarchy) 
} 

按鈕立即被禁用,但仍然可以通過點擊多次很快引發多個「的onClick」事件。 (即performTaskOnce被稱爲多次)。在按鈕被實際禁用之前,似乎onClick事件已排隊。

我可以通過檢查每個onClick句柄來解決問題,相應的按鈕是否已被禁用,但看起來像一個黑客。有沒有更好的方法來避免這個問題?

這個問題發生在Android 2.3.6上,我無法在Android 4.0.3上重現它。但鑑於4.x設備的稀少性,它不能排除舊設備。

+0

這個問題讓我煩惱了幾天.. – mohnage7

回答

7

你可以一個布爾變量當按鈕設置爲true點擊並在完成點擊處理後將其設置爲false。

通過這種方式,您可以忽略多次點擊,而不必禁用該按鈕,可能會避免令人討厭的按鈕閃爍。

boolean processClick=true; 
someButton.setOnClickListener(new OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     if(processClick) 
     { 
     someButton.setEnabled(false); 
     someButton.setClickable(false); 
     someButton.setVisibility(View.GONE); 
     performTaskOnce(); 
     } 
     processClick=false; 
     } 
    }); 

private void performTaskOnce() { 
    Log.i("myapp", "Performing task"); 
    //Do something nontrivial that takes a few ms (like changing the view hierarchy) 
} 
+3

這似乎最簡單。在iOS中,UIApplication類具有可以全局執行此操作的'beginIgnoringInteractionEvents'消息。有時候這很好。但是,我無法找到適用於Android的等效項。你也可以使用一個簡單的後衛「if(!processClick)return」。這會讓你的嵌套更少一些。 –

+0

@DaveCameron +1完全同意你 –

-1

聲明varieble 並以此把它作爲

boolean boo = false; 
someButton.setOnClickListener(new OnClickListener() { 
@Override 
public void onClick(View v) { 
if(boo==false){ 
    someButton.setEnabled(false); 
    someButton.setClickable(false); 
    someButton.setVisibility(View.GONE); 
    boo = true; 
} 


    } 
}); 

可以防止你的按鈕多次點擊

希望它能幫助

+1

對此使用一個int,並遞增它,不如一個標誌清晰。您還沒有展示如何/何時將其設置回零。另外,爲什麼一個類變量,而不是一個實例變量? –

4

在保持DRY的利益:

// Implementation 
public abstract class OneShotClickListener implements View.OnClickListener { 
    private boolean hasClicked; 

    @Override public final void onClick(View v) { 
     if (!hasClicked) { 
      onClicked(v); 
      hasClicked = true; 
     } 
    } 

    public abstract void onClicked(View v); 
} 

// Usage example 
public class MyActivity extends Activity { 
    private View myView; 

    @Override protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     myView.setOnClickListener(new OneShotClickListener() { 
      @Override public void onClicked(View v) { 
       // do clicky stuff 
      } 
     }); 
    } 
} 
+0

乾淨的代碼是乾淨的;) – mohnage7

1

有點晚了,但是這可能是使用的人。在我的情況下,我打電話給另一個活動。

聲明一個布爾值;

boolean clickable; 

在點擊偵聽器中;

if(clickable){ 
    // Launch other activity 
    clickable = false; 
} 

當onResume被調用時啓用;

@Override 
public void onResume() { 
    Log.e(TAG, "onResume"); 
    super.onResume(); 
    clickable = true; 
}