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
相关产品推荐
相关产品推荐

