You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose:如何将焦点颜色与涟漪颜色分开设置

解决Jetpack Compose中点击涟漪与焦点状态样式分离的问题

核心问题分析

你当前的代码中,clickable里的ripple会同时响应按压和焦点两种交互状态,导致焦点时出现黑色背景,和自定义的边框焦点样式冲突。要实现点击涟漪颜色与焦点状态独立控制,最直接的方案是自定义Indication,只让它响应按压事件,忽略焦点事件。

解决方案:自定义点击专属涟漪

实现一个仅在按压时生效的Indication,这样焦点状态不会触发涟漪的颜色绘制,同时保留点击涟漪动画:

class ClickOnlyRipple(
    private val color: Color,
    private val bounded: Boolean = true,
    private val radius: Dp = Dp.Unspecified
) : Indication {
    @Composable
    override fun rememberUpdatedInstance(interactionSource: InteractionSource): IndicationInstance {
        // 复用系统默认的涟漪逻辑,但只在按压时触发
        val systemRipple = rememberRipple(color = color, bounded = bounded, radius = radius)
        val isPressed = interactionSource.collectIsPressedAsState().value

        return remember(systemRipple, isPressed) {
            object : IndicationInstance {
                override fun ContentDrawScope.drawIndication() {
                    if (isPressed) {
                        with(systemRipple) { drawIndication() }
                    } else {
                        drawContent()
                    }
                }
            }
        }
    }
}

// 扩展函数简化调用
fun rippleClickOnly(
    color: Color,
    bounded: Boolean = true,
    radius: Dp = Dp.Unspecified
): Indication = ClickOnlyRipple(color, bounded, radius)

替换原有代码中的涟漪

把clickable里的ripple替换成自定义的rippleClickOnly即可:

.border(
    width = 1.dp,
    shape = shape,
    color = if (interactionSource.collectIsFocusedAsState().value) Color.Black else Color.Transparent
)
.clickable(
    enabled = true,
    interactionSource = interactionSource,
    indication = rippleClickOnly(Color.Black), // 使用自定义涟漪
    onClick = onClick,
    role = role
)

效果说明

  • 点击按压时:正常显示黑色的涟漪动画
  • 焦点状态时:仅显示你自定义的黑色边框,不会出现涟漪带来的黑色背景

内容的提问来源于stack exchange,提问作者Kristopher wolff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 06:27:22