🖱️
Jetpack Compose での多重タップを防ぐコードを考えた
タイトルのとおり、連打されて不具合が起きて困ってたので、防ぐコードを書いた。
なんとなく動いているが、きちんとできているかはわからない。
(2024/11/02 14:31 追記 - どうやらうまく動かない場合があるぽい)
(2024/11/02 23:07 追記 - isClickable を MutableState にすることで改善した)
ClickState
タップ可能かどうかを判定する変数がほしかったので State を作った。
data class ClickState(
val recycleTimeMillis: Long = 1000,
) {
var isClickable: Boolean by mutableStateOf(true)
}
rememberClickState()
フラグを保持していてほしいのと、自動的にまたタップできるように戻って欲しいので LaunchedEffect
と組み合わせた関数を作成。
@Composable
fun rememberClickState(
recycleTimeMillis: Long = 1000,
): ClickState {
val state = remember { ClickState(recycleTimeMillis = recycleTimeMillis) }
LaunchedEffect(state.isClickable) {
if (state.isClickable) return@LaunchedEffect
delay(state.recycleTimeMillis)
state.isClickable = true
}
return state
}
safeClick()
ClickState
を扱う関数をシンプルな形で書いた。
fun safeClick(
clickState: ClickState,
onClick: () -> Unit,
) {
if (clickState.isClickable) {
clickState.isClickable = false
onClick()
}
}
使うとき
この時点では以下のようにして使う。
val clickState = rememberClickState()
FooView(
onClickBack = {
safeClick(clickState) {
navController.popBackStack()
}
}
}
safe()
カッコが煩わしく感じたので少しだけ簡略化して書けるように safe()
を作った。
safeClick()
だと名前被りでダメだった。
もうちょっとマシな名前をつけたい気持ちはある。
fun safe(
clickState: ClickState,
onClick: () -> Unit,
): () -> Unit {
return {
safeClick(
clickState = clickState,
onClick = onClick,
)
}
}
使うとき
ほんとにちょっとだけ簡略化できる。
val clickState = rememberClickState()
FooView(
onClickBack = safe(clickState) {
navController.popBackStack()
}
}
最後に
結構いい感じに書けたんじゃないだろうか ✨
もっと良い方法があったら教えてほしい。
Discussion