Android事件分发(三)

到了这个环节,我们主要研究requestDisallowInterceptTouchEvent的使用。我们之前对这个方法的通俗解释是“请求父亲不要拦截给我的事件”。
首先,看一下官方源码的解释。

Called when a child does not want this parent and its ancestors to intercept touch events with {@linkViewGroup#onInterceptTouchEvent(MotionEvent)}.
当孩子不希望他的父亲们通过onInterceptTouchEvent(MotionEvent)时调用该方法来拦截事件。注意:这里是父亲们哦

This parent should pass this call onto its parents. This parent must obey this request for the duration of the touch (that is, only clear the flag after this parent has received an up or a cancel
这个子孩子的父亲应该将这个请求告知他的父亲,该父亲必须在touch事件中遵循该请求(即,当该父亲收到up或者cancel事件时,才会取消这个标志位)

再看看ViewGroup的dispatchTouchEvent方法中的一段代码

if (!disallowIntercept) {
intercepted = onInterceptTouchEvent(ev);
ev.setAction(action); // restore action in case it was changed
} else {
intercepted = false;
}
当我们调用requestDisallowInterceptTouchEvent其实就是改变父类的
disallowIntercept这个标志位,如果我们将其设置为false,即请求不拦截
那么父类的onInterceptTouchEvent方法根本不会被调用。
我的疑问
如果父类直接就把DOWN事件给拦截了,那么这个方法还有意义吗?我究竟在什么时候才可以请求呢?
1. 正常的实验
首先,我们必须让父亲是可以拦截MOVE事件的。如果父亲一旦拦截了事件,那么这个手势剩下的事件都不会被子类拿到了,那么子类是无法请求不拦截的,除非下一个手势的到来,disallowIntercept标志位才会被置位。
DOWN事件不拦截,在MOVE事件发生时请求父亲拦截
Group_inner
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
System.out.println(“Group_inner尝试截断view的事件”);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
return false;
case MotionEvent.ACTION_MOVE:
return true; //父亲会拦截MOVE事件
case MotionEvent.ACTION_UP:
return false;
default:
}
return super.onInterceptTouchEvent(event);

    Event_view
    > @Override
public boolean dispatchTouchEvent(MotionEvent event) {
    System.out.println("view开始分发事件");
    //System.out.println("Y:"+event.getY());
    if (event.getY() > 100) {
        getParent().requestDisallowInterceptTouchEvent(false);//拦截
    }else{
        getParent().requestDisallowInterceptTouchEvent(true);//不拦截
    }
    return super.dispatchTouchEvent(event);
}
我们意图很明显,Group_inner不会拦截DOWN事件,Event_view必须获得DOWN事件,然后请求父亲不要拦截他的事件,即改变了disallowIntercept这个标志位。然后来了MOVE事件,父类是希望拦截MOVE事件的,可惜他的标志位已经被子类改变,无法执行onInterceptTouchEvent方法。但是一旦Y值超过了100,那么子类重新请求父类拦截,后面的一切都顺理成章了。
>06-24 11:29:48.536: I/System.out(765): eventView---DOWN事件,自己处理

06-24 11:29:48.666: I/System.out(765): eventView—MOVE事件,自己处理
06-24 11:29:48.686: I/System.out(765): eventView—MOVE事件,自己处理
06-24 11:29:48.756: I/System.out(765): Y:113.230774
06-24 11:29:48.766: I/System.out(765): group_inner分发事件
06-24 11:29:48.776: I/System.out(765): Group_inner拦截了MOVE事件
06-24 11:29:48.776: I/System.out(765): Y:123.29939
06-24 11:29:48.776: I/System.out(765): eventView—CANCEL事件,自己处理
06-24 11:29:48.786: I/System.out(765): group_inner—MOVE事件,自己处理
通过日志,很多前面的结论再一次得到了验证
父亲拦截了MOVE事件后,该MOVE事件变成了一个CANCEL事件传递到了子类
后续的MOVE事件再也没传到父亲的onInterceptTouchEvent方法中,而是直接到onTouchEvent中被处理了
2. 不正常的实验
假如Group_inner直接拦截了DOWN事件呢?

06-24 11:49:12.315: I/System.out(810): Group_inner尝试截断view的事件
06-24 11:49:12.315: I/System.out(810): group_inner—DOWN事件,自己处理
06-24 11:49:12.405: I/System.out(810): group_inner—MOVE事件,自己处理
很明显,子孩子根本没有机会啊

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值