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

如何在使用PointerInput修饰符时添加点击涟漪效果?

在Jetpack Compose中为PointerInput手势添加涟漪效果

要在使用PointerInput处理onTap、onLongPress、onPress手势的同时保留涟漪效果,需要手动关联交互状态和涟漪指示器,具体实现如下:

核心思路

clickable修饰符自带涟漪的原因是它内部封装了indication和interactionSource来跟踪交互状态。我们需要手动添加这两个组件,并在PointerInput的手势逻辑中同步更新交互状态,以此触发涟漪效果。

修改后的CustomKey组件代码

import androidx.compose.foundation.Indication
import androidx.compose.foundation.LocalIndication
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.PressInteraction
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.pointerInput
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

@Composable
fun CustomKey(
    text: String,
    onTap: () -> Unit,
    onLongPress: () -> Unit,
    onPress: () -> Unit,
    modifier: Modifier = Modifier
) {
    // 创建可记忆的交互状态源,用于跟踪按压等交互行为
    val interactionSource = remember { MutableInteractionSource() }
    // 获取当前主题下的默认涟漪指示器
    val indication: Indication = LocalIndication.current

    Box(
        modifier = modifier
            .size(60.dp)
            // 关联交互状态与涟漪指示器,启用涟漪效果
            .indication(interactionSource, indication)
            .pointerInput(Unit) {
                detectTapAndPress(
                    onPress = { offset ->
                        // 发送按压开始事件,触发涟漪显示
                        val press = PressInteraction.Press(offset)
                        interactionSource.emit(press)
                        onPress()
                        try {
                            awaitRelease()
                            // 发送按压释放事件,结束涟漪
                            interactionSource.emit(PressInteraction.Release(press))
                        } catch (cancellation: Throwable) {
                            // 发送取消事件,终止涟漪
                            interactionSource.emit(PressInteraction.Cancel(press))
                            throw cancellation
                        }
                    },
                    onTap = { onTap() },
                    onLongPress = { onLongPress() }
                )
            }
    ) {
        Text(text = text)
    }
}

关键部分说明

  • MutableInteractionSource: 记录组件的交互状态(按压、释放、取消),是触发涟漪的核心载体。
  • LocalIndication.current: 获取系统主题默认的涟漪样式,保证和原生clickable的视觉表现一致。
  • detectTapAndPress: 内置手势检测器,已封装onPress、onTap、onLongPress逻辑,只需在onPress中同步发送交互事件,就能让涟漪和手势生命周期完全匹配。
  • 交互事件同步: 按压开始发送PressInteraction.Press、释放发送Release、取消发送Cancel,确保涟漪的显示/消失逻辑和手势行为同步。

内容的提问来源于stack exchange,提问作者ShahZaman Rai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 16:57:15