2012-06-01 15 views
19

ボタンが1回だけ呼び出されるべきアクションをトリガーします。アクションが実行される前にボタンが無効との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

を助ける願っていvarieble を宣言し、それを使用しますクリックが処理されたらfalseに設定します。

このようにして、複数のクリックを無視し、ボタンを無効にする必要がなく、ボタンのちらつきを避けることができます。 DRYを保つの関心で

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

あなたがボタンを複数回クリックを防止するため、このことによって

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; 
} 


    } 
}); 

として

はそれが時にボタンあなたがtrueにブール変数を設定することができ

+1

intを使用してこれを増分すると、フラグよりもあまり明確ではありません。また、どのようにしていつゼロに戻すかを示していません。また、なぜインスタンス変数の代わりにクラス変数? –

4

// 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; 
} 
関連する問題