Android 事件传递

getAction()getActionMasked()

getAction() 是以前的版本出来的

getActionMasked() 是为了多点触控, 现在用的话都选这个就好

shouldDelayChildPressedState()

自定义容器的时候, 如果不需要滚动, 那么需要重写 shouldDelayChildPressedState() , 并且返回 false , 这个方法如果要滚动的话, 会延迟 press 的状态

事件调用

正常情况下是

  • 父容器的 dispatchTouchEvent()

  • -> 父容器的 boolean result = onInterceptTouchEvent()

    • -> 如果 resulttrue , 那么会调用 父容器自己的 onTouchEvent()

    • 如果 resultfalse , 会调用子 ViewonTouchEvent

假设现在的需求是 RecyclerView , 某个 holder 里面的一个子 View 设置了点击事件
  • 当手指触摸到子 View 的时候父容器默认不拦截,

    • 如果手指直接抬起, 那么就响应子 View 的点击事件

    • 如果手指移动, 移动距离达到了设定的阈值, 那么 RecyclerView 的 onInterceptTouchEvent()return true , 把事件接管, 然后给子 View 一个 ACTION_CANCEL 事件

requestDisallowInterceptTouchEvent()

有的时候子 View 不想被父容器拦截事件, 就可以在 onTouchEvent()DOWN 事件的时候调用 parent.requestDisallowInterceptTouchEvent(true) 然后 return true

这样后续的 MOVE 事件就会一直到自己的 onTouchEvent(), 当达到一定条件自己不需要处理事件了调用 parent.requestDisallowInterceptTouchEvent(false)

这个时候如果父容器的 onInterceptTouchEvent() 返回了 true , 那么就会接收到一个 CANCEL 事件, 然后后续的事件也不会再有了

事件传递伪代码

open class TestView {

    open fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        return onTouchEvent(ev)
    }

    open fun onTouchEvent(ev: MotionEvent): Boolean {
        return false
    }
}

open class TestViewGroup : TestView() {

    private var mChild: TestView? = null

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        return if (onInterceptTouchEvent(ev)) {
            return onTouchEvent(ev)
        } else {
            mChild?.onTouchEvent(ev) ?: super.dispatchTouchEvent(ev)
        }
    }

    open fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
        return false
    }

    override fun onTouchEvent(ev: MotionEvent): Boolean {
        return super.onTouchEvent(ev)
    }
}

class MLayout : TestViewGroup() {
    override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
        return super.onInterceptTouchEvent(ev)
    }

    override fun onTouchEvent(ev: MotionEvent): Boolean {
        return super.onTouchEvent(ev)
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值