Android View的事件分发机制笔记

  • 涉及到的几个概念:

    同一个事件序列:手指接触屏幕的那一刻起,到手指离开屏幕的那一刻结束。这个过程中产生的一系列事件,以down事件开始,中间可能包含多个move事件,最终以up事件结束。正常情况下,一个事件序列只能被一个view拦截且消耗,特殊情况下,这个view也可以将本该自己处理的事件通过onTouchEvent强行传递给子view处理。


  • 事件传递规则
    public boolean dispatchTouchEvent(MotionEvent ev)用于事件分发。返回结果表示是否消耗当前事件。
    public boolean onInterceptTouchEvent(MotionEvent ev)只有ViewGroup有该方法。用来判断是否拦截某个事件。返回结果表示是否拦截当前事件。默认返回false
    onTouchEvent(MotionEvent event)具体处理事件。返回结果表示是否消耗当前事件。如果不消耗,在同一个事件序列中,当前view无法再次接受到该事件。

上述3个方法关系伪代码如下(摘自《Android开发艺术探索》):

public boolean dispatchTouchEvent(MotionEvent ev) {
        boolean consume=false;
        if(onInterceptTouchEvent(ev))
        {
            consume=onTouchEvent(ev);
        }else{
            consume= child.dispatchTouchEvent();//由下级view的dispatchTouchEvent()决定。
        }
        return consume;
    }

注意:当一个view被设置了OnTouchListener,这时OnTouchListener中的onTouch方法会优先于这个View的onTouchEvent方法。当且仅当OnTouchListener中的onTouch返回false时View自己的onTouchEvent会被执行。
view的dispatchTouchEvent源码

ViewGroup的dispatchTouchEvent部分源码

因此改进后的事件传递伪代码如下:

public boolean dispatchTouchEvent(MotionEvent ev) {
        boolean consume=disallowIntercept;//由子View设置给父View
        if(!consume)
        {
            consume=onInterceptTouchEvent(ev);
        }
        if(consume)
        {

            if(mOnTouchListener!=null)
            {
                consume=mOnTouchListener.onTouch(this,ev);//优先执行
            }
            if(!consume)
            {
                consume=onTouchEvent(ev);
            }
        }else{
            consume= child.dispatchTouchEvent();
        }
        return consume;
    }

事件传递顺序:Activity->Window->View

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值