背景
在项目中发现我明明在最上层的activity
中的一个DrawerLayout
对象设置了如下代码:
/**
* 超级白板的整体点击事件
* 保证topBar在合适的时机出现
*/
binding.layoutMainDrawer.setOnTouchListener { _, event ->
if (event.action == MotionEvent.ACTION_DOWN) {
val isVisible = binding.layoutTopBar.visibility == View.VISIBLE
binding.layoutTopBar.visibility = if (isVisible) View.GONE else View.VISIBLE
if (!isVisible) {
handler.removeCallbacks(hideTopBarRunnable)
handler.postDelayed(hideTopBarRunnable, 5000)
}
}
false
}
该代码的作用的在点击的时候显示一下TopBar
一个自定义的UI组件。
但是发现点击超级白板(你可以理解为一个画板组件)部分上述代码就没有触发。这是怎么回事呢?
PS: 超级白板组件是在DrawerLayout内一个自定义的ViewGroup(约束布局)的一部分UI组件
分析
首先针对Touch事件的分发机制进行梳理和学习。
重点在于以下几个分发和处理方法
dispatchTouchEvent
和dispatchTouchEvent
方法以及onInterceptTouchEvent
参考1 参考2
解决
那么按照分析的思路:
最上层的touch事件在底下被人消费了(即返回true)。那么就得在分发的时候选择是否分发。
那么我就在包含超级白板的父布局中重写了分发逻辑:
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
val isBlankBoardShowing = binding.mainBlankSuperboard.visibility == View.VISIBLE
// 如果是没有权限管理就不用分发到超级白板这里
if(!ClassRoomManager.me().sharable && !isBlankBoardShowing){
return false
}
return super.dispatchTouchEvent(ev)
}
参考3