事件分发拦截机制

参考链接:http://blog.csdn.net/pi9nc/article/details/9281829#t1

1.了解Android系统的事件拦截机制需要先了解触摸事件,Android触摸事件封装了一个类——MotionEvent.在MotionEvent中我们可以通过event.getY()、event.getX()或者是event.getRawY()、event.getRawX()获取到触摸点的坐标。还可以获取到事件的点击类型,比如MotionEvent.Action_Down、MotionEvent.Action_Move、MotionEvent.Action_Up,在不同的动作中实现不同的逻辑。

2.我们知道 Android 中的View结构是树形结构,view可以放在viewgroup中,但是当view放在一个viewgroup里面,这个viewgroup又可以放在另一个viewgroup中,这样是可以多层嵌套的,当我们队view进行操作的时候,我们到底将触摸事件分配给你哪一个view呢?这就是我们要探讨的问题。

3.代码部分非常简单,创建三个自定义的view。MyViewGroupA/MyViewGroupB/MyView.分别在ViewGroup中重写如下的三个方法.

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.d("keke", "MyViewGroupA---- dispatchTouchEvent" + ev.getAction());
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.d("keke", "MyViewGroupA---- onInterceptTouchEvent" + ev.getAction());
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.d("keke", "MyViewGroupA---- onTouchEvent" + event.getAction());
        return super.onTouchEvent(event);
    }

MyView中重写两个方法

 @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.d("keke", "MyView---- onTouchEvent" + event.getAction());
        return super.onTouchEvent(event);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        Log.d("keke", "MyView----dispatchTouchEvent" + event.getAction());
        return super.dispatchTouchEvent(event);
    }

4.测试结果如下:

1.不修改任何返回值,代码执行流程如下:
D/keke: MyViewGroupA---- dispatchTouchEvent----0
D/keke: MyViewGroupA---- onInterceptTouchEvent----0
D/keke: MyViewGroupB----  dispatchTouchEvent----0
D/keke: MyViewGroupB---- onInterceptTouchEvent----0
D/keke: MyView----dispatchTouchEvent----0
D/keke: MyView---- onTouchEvent----0
D/keke: MyViewGroupB---- onTouchEvent----0
D/keke: MyViewGroupA---- onTouchEvent----0

所以默认的就是:A(分发)—> A(拦截)—>B(分发)—> B(拦截)—>MyView(分发)—> MyView(处理)—>B(处理)—>A()

2.现在假设在MyViewGroupA分发之后就进行事件的拦截,即事件由MyViewGroupA自己进行处理。那么结果又是这样的:
D/keke: MyViewGroupA---- dispatchTouchEvent----0
D/keke: MyViewGroupA---- onInterceptTouchEvent----0
D/keke: MyViewGroupA---- onTouchEvent----0

当MyViewGroupA中的onInterceptTouchEvent返回true的时候,也就是把事件给拦截了,也就没有MyViewGroupB和MyView的什么事儿了。也就是A(分发)—> A(拦截)—>A(处理)

3现在假设在MyViewGroupB分发之后就进行事件的拦截,即事件由MyViewGroupB自己进行处理。那么结果又是这样的:
D/keke: MyViewGroupA---- dispatchTouchEvent----0
D/keke: MyViewGroupA---- onInterceptTouchEvent----0
D/keke: MyViewGroupB----  dispatchTouchEvent----0
D/keke: MyViewGroupB---- onInterceptTouchEvent----0
D/keke: MyViewGroupB---- onTouchEvent----0
D/keke: MyViewGroupA---- onTouchEvent----0

流程就是:A(分发)—> A(拦截)—>B(分发)—> B(拦截)—>B(处理)—> A(),B处理完成后就通知A即可。

以上是在事件拦截的时候通过返回值的控制。对应的view处理的拦截事件,下面来看看事件的处理,即onTouchEvent事件。

4.当MyView返回值为true或者是false的时候的情况

当为true表示的触摸事件最终由MyView来处理,不要继续向上级进行转发。

D/keke: MyViewGroupA---- dispatchTouchEvent----0
D/keke: MyViewGroupA---- onInterceptTouchEvent----0
D/keke: MyViewGroupB----  dispatchTouchEvent----0
D/keke: MyViewGroupB---- onInterceptTouchEvent----0
D/keke: MyView----dispatchTouchEvent----0
D/keke: MyView---- onTouchEvent----0

当返回false的时候表示的是MyView不处理触摸事件,所以继续向上级进行转发。

D/keke: MyViewGroupA---- dispatchTouchEvent----0
D/keke: MyViewGroupA---- onInterceptTouchEvent----0
D/keke: MyViewGroupB----  dispatchTouchEvent----0
D/keke: MyViewGroupB---- onInterceptTouchEvent----0
D/keke: MyView----dispatchTouchEvent----0
D/keke: MyView---- onTouchEvent----0
D/keke: MyViewGroupB---- onTouchEvent----0
D/keke: MyViewGroupA---- onTouchEvent----0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值