前人未踏の領域へ Androidアプリ開発編

Androidアプリ開発に関する調査メモ置き場。古い記事にはアプリ以外も含まれます。

Jetpack Compose:特定の条件のときだけClickableにしたい

内容

あるコンポーサブルをに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 }
}

その他

昔書いたコード(上の注意点)が良くなかったと思い修正しようとしたが記事が見当たらなかった上に クリックイベント拾わないケースに気づいて結局完全にはなくせないことが判明。