Jetpack ComposeのModifier.clickable
を使うと自動的にリップルエフェクト(タップした点から波紋が広がるようなエフェクト)が有効になります。今回はこのリップルエフェクトを無効にする方法を紹介します。
やりたいこと
こんな感じで、リップルエフェクトを無効にします。
サンプル
ソースコードはGitHubにあります。
主な環境は以下の通りです。
- Kotlin 1.7210
- Compose Compiler 1.3.2
- Compose Libraries 1.2.1
- Material3 1.0.0-rc01
- Accompanist 0.25.1
二つのModifier.clickable
標準のclickable
には引数が少ないバージョンと引数が多いバージョンがあります。
fun Modifier.clickable(
enabled: Boolean = true,
onClickLabel: String? = null,
role: Role? = null,
onClick: () -> Unit
): Modifier
fun Modifier.clickable(
interactionSource: MutableInteractionSource,
indication: Indication?,
enabled: Boolean = true,
onClickLabel: String? = null,
role: Role? = null,
onClick: () -> Unit
): Modifier
シンプルにModifier.clickable { ... }
という書き方をした時に呼び出されるのは、引数が少ない方です。引数が少ない方のclickable
は、内部で引数が多い方を呼び出します。その時にindication
にLocalIndication
を渡しているので、デフォルトではリップルエフェクトが発生します。
リップルエフェクトを無効にするには、引数が多い方のclickable
にindication = null
を指定すればOKです。interactionSource
にはremember { MutableInteractionSource() }
を指定するのが定型です。
Modifier.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = null,
) {
// onClickの処理
}
Modifierの拡張関数を作る
以下のようにModifierの拡張関数を作っておくと、使いまわせて便利です。
fun Modifier.clickableNoRipple(
enabled: Boolean = true,
onClickLabel: String? = null,
role: Role? = null,
onClick: () -> Unit,
): Modifier = composed {
this.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = null,
enabled = enabled,
onClickLabel = onClickLabel,
role = role,
onClick = onClick
)
}
ポイントは、composed
です。Developer Guideには以下のように説明されています。
変更する要素ごとに、コンポーズされる
https://developer.android.com/jetpack/compose/modifiers-list?hl=jaModifier
のジャストインタイム コンポジションを宣言します。
ちょっと日本語が難しいですが、、、要するに、状態を持つModifierを複数個所で同時に使っても問題ないようにしてくれる、ということだと思います。今回の場合はremember { MutableInteractionSource() }
の部分が状態(ステートフル)ですね。
サンプルソース
冒頭の動画のサンプルソースはこんな感じです。一つ目のコンポーザブルには、標準の引数が少ない方のclickable
を使っているので、リップルエフェクトが発生します。二つ目のコンポーザブルには、先ほど作ったclickableNoRipple
を使っているので、リップルエフェクトが無効になります。
@Composable
fun NoRippleEffectSample() {
Column(
...
) {
var text1 by remember { mutableStateOf("Click me") }
var text2 by remember { mutableStateOf("Click me") }
ClickMe(
title = text1,
subTitle = "(Ripple effect)",
color = MaterialTheme.colorScheme.secondary,
modifier = Modifier.clickable { text1 += "!" }
)
ClickMe(
title = text2,
subTitle = "(No ripple effect)",
color = MaterialTheme.colorScheme.tertiary,
modifier = Modifier.clickableNoRipple { text2 += "!" }
)
}
}
ClickMeの中身なども含めてソースコードを見たい方は、GitHubを参照してください。
コンテンツは随時追加していきます。