Compose自定义弹跳按钮动画点击事件失效问题求助
问题原因
你代码里同时用了clickable和pointerInput处理触摸事件,pointerInput会拦截所有触摸事件,导致clickable的onClick完全得不到触发机会,这就是点击无反应的核心原因。
解决方案
移除clickable修饰符,直接在pointerInput的触摸逻辑里处理点击回调,同时保留弹跳动画效果。另外可以优化动画逻辑,比如点击按下时缩小,抬起(或取消)时恢复,并且只有在正常抬起时才触发点击事件。
修改后的代码
fun Modifier.bounceClick( onClick: () -> Unit, animationDuration: Int = 100, scaleDown: Float = 0.9f ) = composed { val scale = remember { Animatable(1f) } this .scale(scale = scale.value) .background( color = Color(0xFF35898F), shape = RoundedCornerShape(size = 12f) ) .pointerInput(Unit) { while (true) { awaitPointerEventScope { // 等待按下事件 awaitFirstDown(requireUnconsumed = false) // 按下时执行缩小动画 launch { scale.animateTo( targetValue = scaleDown, animationSpec = tween(animationDuration) ) } // 等待抬起或触摸取消事件 val upEvent = waitForUpOrCancellation() // 执行恢复原大小的动画 launch { scale.animateTo( targetValue = 1f, animationSpec = tween(animationDuration) ) } // 只有用户正常抬起手指时,才触发点击回调 upEvent?.let { onClick() } } } } }
关键改动说明
- 移除
clickable修饰符,解决触摸事件拦截冲突 - 直接使用
pointerInput内部的launch执行动画,无需额外声明rememberCoroutineScope - 通过
waitForUpOrCancellation()的返回值判断有效点击:返回非null表示用户正常完成点击动作,此时触发onClick - 简化抬起阶段的动画逻辑,直接从缩小状态恢复至原大小,去掉冗余的重复设置步骤
内容的提问来源于stack exchange,提问作者teol
相关产品推荐
相关产品推荐

