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

Android开发中setOnClickListener点击事件偶尔无响应是什么原因?

问题根因

你使用的TranslateAnimation属于传统补间动画,仅会修改View的渲染绘制位置,不会修改View的实际布局坐标。设置fillAfter=true后,按钮仅视觉上停在动画结束位置,可点击区域仍保留在XML定义的原始位置,因此点击视觉位置无响应。
同时你为按钮同时执行淡入、上滑两个补间动画,动画执行过程中View也可能无法正常捕获触摸事件。

修复方案

方案1(推荐):替换补间动画为属性动画

属性动画会直接修改View的真实属性,点击区域会同步跟随视觉位置移动,无需额外适配:

// 修改上滑实现为属性动画
fun slideUp(view : View, time : Int) {
    view.animate()
        .translationY(-300f)
        .setDuration(time.toLong())
        .start()
}

// 修改淡入实现为属性动画
fun fadeIn(view: View, time: Int) {
    // 先修改可见性,保证动画结束后可正常响应点击
    view.visibility = View.VISIBLE
    view.alpha = 0f
    view.animate()
        .alpha(1f)
        .setDuration(time.toLong())
        .start()
}

方案2:保留补间动画,结束后手动更新布局位置

如果必须使用原有补间动画实现,给动画添加结束监听,动画完成后手动修改View的真实布局坐标:

fun slideUp(view : View, time : Int) {
    val animation = TranslateAnimation(0f, 0f, 0f, -300f )
    animation.duration = time.toLong()
    animation.fillAfter = true
    animation.setAnimationListener(object : Animation.AnimationListener {
        override fun onAnimationStart(animation: Animation?) {}
        override fun onAnimationRepeat(animation: Animation?) {}
        override fun onAnimationEnd(animation: Animation?) {
            // 动画结束后更新View的真实位置
            val params = view.layoutParams as ConstraintLayout.LayoutParams
            params.topMargin = params.topMargin - 300
            view.layoutParams = params
            // 清除动画,避免后续冲突
            view.clearAnimation()
        }
    })
    view.startAnimation(animation)
}

额外优化项

给XML中作为按钮的RelativeLayout添加如下属性,避免子TextView抢夺点击事件:

android:descendantFocusability="blocksDescendants"
android:clickable="true"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 01:06:03