android事件传递——1.概述

1 事件传递流程概述

事件的传递是由最顶层(即最外层)的父控件开始,一层一层向下传递,直到最底层(即最内层)的子控件。若最底层的子控件没有消耗掉事件,则:事件又会从最底层的子控件开始,一层一层向上传递,直到最顶层的父控件。

当父控件不拦截事件(onInterceptTouchEvent返回true,代表拦截事件)时,事件才会向下传递给其子控件。含有子view的viewGroup默认都不会拦截。当子控件不消耗掉事件(onTouchEvent返回true,代表消耗掉事件)时,事件才会向上传递给其父控件。

以上为完整的事件传递流程,后面我们将知道,只有down事件会走完整的事件传递流程,move、up等后续事件走的都是简化的事件传递流程。

2 事件传递方法

以ViewGroup为例:

  • public boolean dispatchTouchEvent(MotionEvent ev):管理事件的分发,返回值表示当前控件或其直接、间接的子控件是否消耗了事件。这个返回值代表的是事件分发的结果,并不会左右事件分发的走向。

  • public boolean onInterceptTouchEvent(MotionEvent ev): 在dispatchTouchEvent方法的内部被调用,返回值表示是否要拦截事件。需要注意的是,一旦拦截了某个事件,那么同一事件序列中的后续事件都不会再经过onInterceptTouchEvent。事件序列:从手指按下,经过移动,到手指抬起,这一系列触摸事件称为一个事件序列。

  • public boolean onTouchEvent(MotionEvent ev):处理事件,返回值表示是否消耗当前事件。

以上三个方法的关系可用下面的伪代码来表示:

public boolean dispatchTouchEvent(MotionEvent ev){
    boolean comsume = false;
    if(onInterceptTouchEvent(ev)){//若拦截,则交给自己的onTouchEvent处理
        comsume = onTouchEvent(ev);
    }else{//若不拦截,则交给子view
        comsume = child.dispatchTouchEvent(ev);
    }
    return comsume;
}
//注意:View没有onInterceptTouchEvent方法,一旦有触摸事件传递给它,它的onTouchEvent方法就会被调用

可见,onInterceptTouchEvent和onTouchEvent都是在dispatchTouchEvent中被调用的:

  • 若onInterceptTouchEvent拦截了事件,则将事件交给自己的onTouchEvent处理
  • 若onInterceptTouchEvent未拦截事件,则将事件往下传递给子view的dispatchTouchEvent

在dispatchTouchEvent中可以通过调用requestDisallowInterceptTouchEvent来请求所有的父控件不要拦截事件:

public boolean dispatchTouchEvent(MotionEvent ev) {
	getParent().requestDisallowInterceptTouchEvent(true);// 请求所有父控件不要拦截事件
	...
}

效果是所有父控件的onInterceptTouchEvent方法都不会被调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值