本題
サルやラットがボタン連打して狂って死ぬ実験は有名ですが、人間もボタンを連打します。
というわけでAndroidでのボタン連打防止機構。やり方そのものはわりと出てくるのですが、自分が考えたやり方が見つからなかったので書きます。
GuardActivity.java
public class GuardActivity extends AppCompatActivity {
// 最後にボタンがタップされた時間
private long mLastClickedTime;
// 連打防止時間.ミリ秒
private static long GUARD_TIME = 200;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ButtonListener listener = new ButtonListener();
// リスナをセットするボタンのID一覧
int[] BUTTON_LIST = {R.id.ButtonEnter, R.id.ButtonExit, R.id.ButtonNext, R.id.ButtonPrev};
for (int buttonId : BUTTON_LIST) {
findViewById(buttonId).setOnClickListener(listener);
}
}
// クリックリスナ
private class ButtonListener implements View.OnClickListener {
@Override
public void onClick(View v) {
long currentTime = System.currentTimeMillis();
if (currentTime - mLastClickedTime < GUARD_TIME) {
// 現在時刻 - 最後にタップされた時間 < 連打防止時間
// の場合は何もしない
return;
}
// 最後にタップされた時間を更新
mLastClickedTime = currentTime;
switch (v.getId()) {
case R.id.ButtonEnter:
// 各ボタンごとの処理
break;
}
}
}
}
連打防止時間の秒数は適宜調整してください。がっつり動作確認はしてないです1。
おまけ
なんでこんなのが必要になったかというとPreferenceFragmentCompatで作ったメニューが連打されたからです。
PreferenceFragmentを使っているっぽいAndroid標準の設定アプリでメニューを連打すると同じ画面が二重に開くので、興味があって暇な人は連打してみましょう。別のボタンを短時間に別々に押しても画面が二重に開きます2。確かNexus5XのOreoで確認しました。機種によってはできないかも。
フレームワークに既にあるものを再実装するって虚無でイヤなのですが、PreferenceFragmentCompatみたいなこまったちゃんの場合は、作り慣れたRecyclerViewやListViewでそれっぽく作ったほうが簡単で幸せです。