問題の一部は、UI ボタンをクリックすると、そのクリックに関連付けられたアクションがまだ完了していなくても、すぐに戻ったり、クリックをキューに入れたりすることです。この応答の範囲を超えた理由により、「作業中」にボタンを無効にするだけでは効果がないことに注意してください。この種の問題にはいくつかの解決策があります。1 つは、基になる「作業」が完了した後にのみ設定されるブール値フラグを使用することです。次に、ボタン アクション ハンドラー内で、フラグがリセットされる前に発生したボタン クリックを無視します。
/**
* Button presses are ignored unless idle.
*/
private void onMyButtonClicked() {
if(idle) {
doWork();
}
}
/**
* Does some work and then restores idle state when finished.
*/
private void doWork() {
idle = false;
// maybe you spin off a worker thread or something else.
// the important thing is that either in that thread's run() or maybe just in the body of
// this doWork() method, you:
idle = true;
}
もう 1 つの一般的なオプションは、時間を使用してフィルター処理することです。すなわち。ボタンを押す最大頻度が 1hz である制限を設定します。
/**
* Determines whether or not a button press should be acted upon. Note that this method
* can be used within any interactive widget's onAction method, not just buttons. This kind of
* filtering is necessary due to the way that Android caches button clicks before processing them.
* See http://code.google.com/p/android/issues/detail?id=20073
* @param timestamp timestamp of the button press in question
* @return True if the timing of this button press falls within the specified threshold
*/
public static synchronized boolean validateButtonPress(long timestamp) {
long delta = timestamp - lastButtonPress;
lastButtonPress = timestamp;
return delta > BUTTON_PRESS_THRESHOLD_MS;
}
次に、次のようにします。
private void onMyButtonClicked() {
if(validateButtonPress(System.currentTimeMillis())) {
doWork();
}
}
この最後の解決策は明らかに非決定論的ですが、ユーザーがモバイル デバイスで 1 秒間に 1 ~ 2 回以上意図的にボタンをクリックすることはほとんどないことを考えると、それほど悪くはありません。