andoird基础-事件分发

原生态android上面的view是树形结构的,view可能会重叠在一起,当我们点击的地方有多个view都可以响应的时候,这个点击事件应该交给谁来处理,就需要事件分发机制。
事件分发的三个重要方法

public boolean dispatchTouchEvent(MotionEvent event)
public boolean onInterceptTouchEvent(MotionEvent event)
public boolean onTouchEvent(MotionEvent event)

MotionEvent取值如下:

    public static final int ACTION_DOWN             = 0;
    public static final int ACTION_UP               = 1;
    public static final int ACTION_MOVE             = 2;
    public static final int ACTION_CANCEL           = 3;

ACTION_DOWN 表示手指按下时发出的消息
ACTION_UP 表示手指抬起时发出的消息
ACTION_MOVE 表示手指移动时发出的消息
ACTION_CANCEL 表示结束事件时手指发出的消息
在这里插入图片描述
注意:
对于Activity来说不需要 onInterceptTouchEvent 方法,因为拦截没有意义,拦截后整个view树都点击不了。
对于view来说,事件要么消费,要么回传,也没有拦截的必要。
因此在Activity,ViewGroup,TextView中都有disPatchTouchEvent方法和onTouchEvent方法。
对于ViewGroup来说,多了一个onInterceptTouchEvent方法。
先说不包含 onInterceptTouchEvent 方法时消息传递过程,再来看包含onInterceptTouchEvent方法时消息传递过程。
2:不包含 onInterceptTouchEvent 方法时 ACTION_DOWN 消息传递过程
什么是拦截?看下面这三个方法都有一个boolean类型的返回值。默认返回false表示没有拦截,即自己不做处理。返回true时,表示自己处理这个事件,就是拦截了。
2.2 在 dispatchTouchEvent 方法中返回 true 拦截消息
2.2.1 在 Activity 的 dispatchTouchEvent 方法中拦截消息
在 Activity 的 dispatchTouchEvent 方法中拦截消息后,消息会直接断掉,不会往任何地方传递,只有 Activity 的 dispatchTouchEvent 方法收到 ACTION_DOWN 消息。
2.2.2 在 ViewGroup 的 dispatchTouchEvent 方法中拦截消息
在 ViewGroup 的 dispatchTouchEvent 方法中拦截消息后,ACTION_DOWN 消息同样会直接停止传递,其他任何子控件都收不到消息。
2.2.2 在 View 的 dispatchTouchEvent 方法中拦截消息
在传递到 View 的 dispatchTouchEvent 方法后,消息就停止传递了。
因此,无论在哪个控件的 dispatchTouchEvent 方法中拦截消息,消息都会直接停止传递,后面的子控件都不会接收到这个消息。
2.3 在 dispatchTouchEvent 方法中返回 false 拦截消息
先说结论:在 dispatchTouchEvent 方法中返回 false 拦截消息后,消息不会直接停止传递,而是向父控件的 onTouchEvent 方法回传。
2.4 在 onTouchEvent 方法中拦截 ACTION_DOWN 消息
onTouchEvent 方法中,默认返回 false,表示不拦截; 当返回 true 时, 表示拦截。
先说结论:
无论哪个控件的 onTouchEvent 方法拦截 ACTION_DOWN 消息, 消息都会直接停止传递, 后面的父控件都不会接收到这个消息。
总结:
dispatchTouchEvent 和 onTouchEvent 方法一旦返回true拦截消息, ACTION_DOWN 消息就会停止传递,正常流程下的后续节点都不会收到 ACTION_DOWN 消息了。
当 dispatchTouchEvent 方法,返回 false 时,首先会拦截 ACTION_DOWN 消息,消息不会继续传给子控件,而是传给父控件的 onTouchEvent,然后继续回传。
3. 在 onInterceptTouchEvent 方法中的 ACTION_DOWN 消息传递流程
3.1 onInterceptTouchEvent 方法的作用
首先,只有 ViewGroup 具有 onInterceptTouchEvent 方法, Activity 和 View 中都没有这个方法。
然后, onInterceptTouchEvent 方法其实就是一个拦截过滤器。每个 ViewGroup 每次在处理消息分发时,都会问一问拦截器要不要拦截(也就是这个消息要不要自己处理)。要处理就返回true,然后交给自己的 onTouchEvent 方法处理。如果不拦截,就继续往子控件传递。默认是不拦截的。
总结:
在 ViewGroup 的 onInterceptTouchEvent 方法中拦截 ACTION_DOWN 消息,会改变 ACTION_DOWN 消息的流向,让它直接流向当前 ViewGroup 的 onTouchEvent 方法。
同样,如果 onTouchEvent 方法没有拦截继续拦截消息,则消息会继续传递。如果某个 onTouchEvent 方法中拦截消息的话, ACTION_DOWN 会直接停止传递。
事件传递流程
Activity -> PhoneWindow -> DecorView -> ViewGroup -> … -> view
典型的责任链模式
如果最后的view也没有消费事件,那么事件就会被依次向上回传直到Activity,如果Activity也没有处理该事件,那么事件就被抛弃。
既保证了事件的有序性,又非常的灵活。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值