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
): Modifierfun 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を参照してください。
コンテンツは随時追加していきます。




