如何在 Jetpack Compose 中单击时禁用波纹效果

问题描述 投票:0回答:8

在 Jetpack Compose 中,当您在可组合项的修饰符上启用

clickable {}
时,默认情况下它会为其启用波纹效果。如何禁用此行为?

示例代码

Row(modifier = Modifier
         .clickable { // action }
)
android android-jetpack android-jetpack-compose
8个回答
137
投票

简短回答
要禁用

null
 修改器中 
indication
 参数中的波纹传递 
clickable

val interactionSource = remember { MutableInteractionSource() }
Column {
    Text(
        text = "Click me without any ripple!",
        modifier = Modifier
            .clickable(
                interactionSource = interactionSource,
                indication = null
            ) {
                /* doSomething() */
            }
    )

为什么它不能与某些可组合项一起用作按钮:

请注意,在某些可组合项中,例如

Button
IconButton
,它不起作用,因为
indication
是由使用
indication = rememberRipple()
的组件在内部定义的。这将使用
Ripple
提供的值创建并记住
RippleTheme

在这种情况下,您无法禁用它,但您可以更改基于

RippleTheme
的波纹的外观。您可以定义自定义 RippleTheme 并使用
LocalRippleTheme
将其应用到您的可组合项。

类似:

CompositionLocalProvider(LocalRippleTheme provides NoRippleTheme) {
    Button(
        onClick = { /*...*/ },
    ) {
       //...
    }
}

与:

private object NoRippleTheme : RippleTheme {
    @Composable
    override fun defaultColor() = Color.Unspecified

    @Composable
    override fun rippleAlpha(): RippleAlpha = RippleAlpha(0.0f,0.0f,0.0f,0.0f)
}

自定义修改器

如果您愿意使用上面相同的代码构建自定义修改器,您可以使用:

fun Modifier.clickableWithoutRipple(
    interactionSource: MutableInteractionSource,
    onClick: () -> Unit
) = composed(
    factory = {
        this.then(
            Modifier.clickable(
                interactionSource = interactionSource,
                indication = null,
                onClick = { onClick() }
            )
        )
    }
)

然后应用它:

    Row(
        modifier = Modifier
            .clickableWithoutRipple(
                interactionSource = interactionSource,
                onClick = { doSomething() }
            )
    ){ 
      //Row content
    }

长答案
如果将

clickable
修饰符 添加到可组合项以使其在其范围内可点击,它将显示
Indication
,如指示参数中指定的那样。

默认情况下,将使用

LocalIndication
的指示。

如果您在层次结构中使用

MaterialTheme
,则由
Ripple
 定义的 
rememberRipple()
将用作组件(例如
Indication
androidx.compose.foundation.clickable
)内的默认
androidx.compose.foundation.indication


102
投票

使用此修饰符扩展:

fun Modifier.noRippleClickable(onClick: () -> Unit): Modifier = composed {
    clickable(indication = null,
        interactionSource = remember { MutableInteractionSource() }) {
        onClick()
    }
}

然后只需将

Modifier.clickable {}
替换为
Modifier.noRippleClickable {}

Row(modifier = Modifier.noRippleClickable { 
  // action 
})

92
投票

要禁用波纹效果,必须将

null
传递给修改器的
indication
属性。

有关 Jetpack Compose 文档中的指示的更多信息

代码

Row(
    modifier = Modifier
        .clickable(
            indication = null, 
            interactionSource = remember { MutableInteractionSource() } // This is mandatory
        ) { 
            // action
        }
)

12
投票

使用按钮时可以这样处理。

创建一个Ripple交互源

class NoRippleInteractionSource : MutableInteractionSource {

override val interactions: Flow<Interaction> = emptyFlow()

override suspend fun emit(interaction: Interaction) {}

override fun tryEmit(interaction: Interaction) = true

}

如果是按钮,您可以通过将波纹交互类作为 interactionSource 参数传递来处理它,即:

 Button(
    onClick = { /*...*/ },
    interactionSource = NoRippleInteractionSource()
) {
    //..
}

此解决方案适用于所有接受 mutableInteractionSource 作为参数的可组合项,例如 Button()TextButton()Switch()

使用可点击修改器时,您可以这样做:

modifier = Modifier.clickable(
                    indication = null,
                    interactionSource = NoRippleInteractionSource()
                ) { /** todo  action here */ }

您还可以进一步修改上述答案并创建扩展函数并重新用于所有可点击的功能,即:

fun Modifier.noRippleClick(onClick:()->Unit):Modifier {
  return this.clickable(
    interactionSource = NoRippleInteractionSource(),
    indication = null
   ){ 
      onClick() 
   } 
 }

您现在可以使用扩展修饰符代替可点击修饰符,即:

modifier = modifier.noRippleClick { /** todo  action here */  }

0
投票

具有其他参数的修饰符扩展:

inline fun Modifier.noRippleClickable(
        enabled: Boolean = true,
        onClickLabel: String? = null,
        role: Role? = null,
        crossinline onClick: ()->Unit
    ): Modifier = composed {
        clickable(
            enabled = enabled,
            indication = null,
            onClickLabel = onClickLabel,
            role = role,
            interactionSource = remember { MutableInteractionSource() }) {
            onClick()
        }
    }

0
投票

创建一个自定义修改器,使可组合项可单击,单击时不会显示波纹效果。

fun Modifier.noRippleClickable(
     onClick: () -> Unit
): Modifier = composed {
    clickable(
        indication = null,
        interactionSource = remember { MutableInteractionSource() }) {
        onClick()
    }
}

之后,您可以像下面这样使用它:

modifier = Modifier.noRippleClickable(
                    onClick = {
                        
                    }),

-1
投票

我使用了@Mahdi-Malv的答案并修改如下:

  • 删除内联和跨内联
  • 按照我的要求修改
fun Modifier.noRippleClickable(
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    indication: Indication? = null,
    enabled: Boolean = true,
    onClickLabel: String? = null,
    role: Role? = null,
    onClick: () -> Unit,
) = clickable(
    interactionSource = interactionSource,
    indication = indication,
    enabled = enabled,
    onClickLabel = onClickLabel,
    role = role,
    onClick = onClick,
)

-2
投票

对于

androidx.compose.foundation
,可点击扩展内有一个
enabled
属性。我认为这是最简单的方法。 链接

fun Modifier.clickable(
    interactionSource: MutableInteractionSource,
    indication: Indication?,
    enabled: Boolean = true,
    onClickLabel: String? = null,
    role: Role? = null,
    onClick: () -> Unit
): Modifier
© www.soinside.com 2019 - 2024. All rights reserved.