内容
あるコンポーサブルをにclickable属性を付与したいが、条件によってはoffにしたい。
クリックイベントを空 {}にしてもタップエフェクトが発生してしまう。どうすればよいか。
対応
- Modifier.clicable()の
enabledパラメータを使う
@Composable
fun SomeText(onClick: (() -> Unit)? = null) {
Row(modifier = Modifier.clickable(enabled = onClick != null){ onClick?.invoke() }) {
}
}
@Composable
fun OtherText(enabled: Boolean, onClick: (() -> Unit) = {}) {
Row(modifier = Modifier.clickable(enabled = enabled){ onClick() }) {
}
}
enabledがfalseになっていればclickアクションは反応せず、タップエフェクトも発生しない。
注意点
この方法だと反応(Ripple Effect)はしなくなるもののイベントそのものは拾ってしまうので 親のComposable側でclickableを定義してあっても無視されてしまう。
それを避けたい場合は run関数などを使って非nullの場合にだけclickableを定義する方法がある。
Box(
modifier = modifier.fillMaxWidth().run {
onClick?.let {
clickable { onClick() }
} ?: this
}
) {
}
というかもうこうしてModifier.clickableでもnullを許容しちゃえばいい気がしてきた。
fun Modifier.clickable(onClick: (() -> Unit)?): Modifier {
return run { onClick?.let { clickable(onClick = it) } ?: this }
}
その他
昔書いたコード(上の注意点)が良くなかったと思い修正しようとしたが記事が見当たらなかった上に クリックイベント拾わないケースに気づいて結局完全にはなくせないことが判明。