【Android】Touch 事件分发逻辑梳理和避坑逻辑(上层设置了setOnTouchListener的事件监听但是没有起作用的原因)

文章讨论了一个在Android开发中遇到的问题,即在DrawerLayout中,点击自定义的超级白板组件时,相关的触摸事件没有被触发。作者通过研究Touch事件的分发机制,发现事件可能在底层被消费。为了解决这个问题,作者在超级白板的父布局中重写了dispatchTouchEvent方法,确保事件能够正确分发。通过这样的调整,修复了点击事件不生效的bug。
摘要由CSDN通过智能技术生成

背景

在项目中发现我明明在最上层的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事件的分发机制进行梳理和学习。
重点在于以下几个分发和处理方法
dispatchTouchEventdispatchTouchEvent方法以及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

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值