升级至API 33后GestureDetector.SimpleOnGestureListener的onScroll方法空指针崩溃问题求助
解决API 33下GestureDetector onScroll方法的NullPointerException问题
问题根源
你遇到的崩溃是因为升级到API 33后,Android框架将GestureDetector.SimpleOnGestureListener#onScroll的参数e1和e2标注为非空(@NonNull),但在实际场景(比如RecyclerView滚动时的触摸事件拦截/传递中断)中,系统仍然可能传入null值。而Kotlin的严格非空检查会触发Intrinsics.checkNotNullParameter,直接抛出NullPointerException。
在API 32及以下版本中,这些参数没有被强制标注为非空,你的代码通过e1.y.let { ... } ?: 0能隐性处理null情况,但升级后Kotlin编译器强制要求参数非空,就把潜在的null问题暴露了出来。
解决方案
我们需要调整onScroll方法的参数声明,允许e1和e2为null,并在方法内部先做空值检查,同时修复触摸事件的返回逻辑避免传递混乱:
1. 修改MyGestureListener的onScroll方法
inner class MyGestureListener : GestureDetector.SimpleOnGestureListener() { override fun onDown(e: MotionEvent): Boolean { return true } // 允许参数为可空类型,添加注解消除编译器的非空不匹配警告 @Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS") override fun onScroll( e1: MotionEvent?, e2: MotionEvent?, distanceX: Float, distanceY: Float ): Boolean { // 先检查e1和e2是否为空,为空则直接返回默认行为 if (e1 == null || e2 == null) { return super.onScroll(e1, e2, distanceX, distanceY) } val diffY = e2.y - e1.y if (diffY < 0) { Log.d("====ON SCROLL====", "On Scroll top") bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED binding.root.setOnClickListener(null) } return true } }
2. 修复触摸事件的返回逻辑
你的触摸监听器没有返回手势检测器的处理结果,这可能导致触摸事件传递混乱,增加e1为null的概率。修改为:
val mDetector = GestureDetectorCompat(requireContext(), MyGestureListener()) binding.root.setOnTouchListener { v, event -> val isHandled = mDetector.onTouchEvent(event) // 只有当手势被处理时才执行点击,符合无障碍要求 if (isHandled) { v.performClick() } // 返回手势处理结果,告诉系统事件是否被消费 isHandled }
额外说明
@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")注解用于消除Kotlin编译器的警告,因为我们故意将Java声明的非空参数改为可空,以适配系统的实际行为。- 空值检查是核心:必须先确认
e1和e2不为null,再执行后续的坐标计算逻辑,从根源避免NPE。 - 修复触摸事件返回值能确保手势事件被正确消费,减少系统传递异常事件的概率。
内容的提问来源于stack exchange,提问作者Ionut
相关产品推荐
相关产品推荐

