ボタン連打による二重起動を防ぐ (Prevent starting twice)

目次

Activity編

どちらかのインテントフラグで防げます。

.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)

Fragment編

if (supportFragmentManager.findFragmentByTag(tag) == null) {
    // まだ追加されていなければ、add, showでフラグメントを追加する
}

AlertDialog編

AlertDialogをDialogFragment化すると前述の方法が使えます。ただ、ダイアログは通常の確認だけでなく、リスト選択もあれば日付ピッカーもあるので、汎用化するのは結構大変かと思います。この辺の定番があるなら教えて欲しい。

ツールバーのボタンを一定時間ロックする

iOSで言うと、ナビゲーションのボタンアイテムに相当する部分。メニューアイテムはViewではないため、isEnableでロックしてから遅延解除します。

private fun MenuItem.debounce(delayMillis: Long = 700) {
    isEnabled = false
    val runnable = Runnable {
        isEnabled = true
    }
    Handler(Looper.getMainLooper()).postDelayed(runnable, delayMillis)
}

fun Toolbar.setOnMenuItemClickListenerDebounced(delayMillis: Long = 700, l: Toolbar.OnMenuItemClickListener?) {
    setOnMenuItemClickListener {
        it.debounce(delayMillis)
        l?.onMenuItemClick(it) ?: false
    }
}
toolbar.setOnMenuItemClickListenerDebounced {
    // クリック処理
    true
}

ボタンを一定時間ロックする

private fun View.debounce(delayMillis: Long = 700) {
    isClickable = false
    val runnable = Runnable {
        isClickable = true
    }
    postDelayed(runnable, delayMillis)
}

fun View.setOnClickListenerDebounced(delayMillis: Long = 700, l: View.OnClickListener?) {
    setOnClickListener {
        it.debounce(delayMillis)
        l?.onClick(it)
    }
}