android 事件分发,onInterceptTouchEvent()和onTouchEvent()总结,OnTouchListener。

本文详细介绍了Android中事件分发的过程,包括View的dispatchTouchEvent、onTouchEvent以及OnTouchListener。重点讲解了onInterceptTouchEvent()如何决定事件是否向下传递,以及onTouchEvent()如何处理事件并决定事件是否被消费。通过理解这两个方法,可以更好地控制事件在视图层次中的流向。此外,还探讨了返回值对事件处理的影响,以及ACTION_DOWN、ACTION_MOVE、ACTION_UP等事件的关系。

概念介绍

1、onInterceptTouchEvent()是用于预处理事件重点onInterceptTouchEvent这个事件是从父控件开始往子控件传的,直到有拦截或者到没有这个事件的view,然后就往回从子到父控件,这次是onTouch的(类似于预处理,当然也可以不处理)并改变事件的传递方向,也就是决定是否允许Touch事件继续向下(子控件)传递,一但返回True(代表事件在当前的viewGroup中会被处理),则向下传递之路被截断(所有子控件将没有机会参与Touch事件),同时把事件传递给当前的控件的onTouchEvent()处理;返回false,则把事件交给子控件的onInterceptTouchEvent()

2、onTouchEvent()用于处理事件(重点onTouch这个事件是从子控件回传到父控件的,一层层向上传),返回值决定当前控件是否消费(consume)了这个事件。也就是说在当前控件在处理完Touch事件后,是否还允许Touch事件继续向上(父控件)传递。返回false,则向上传递给父控件,详细一点就是这个touch事件就给了父控件,那么后面的up事件就是到这里touch触发,不会在传给它的子控件。如果父控件依然是false,那touch的处理就给到父控件的父控件,那么up的事件处理都在父控件的父控件,不会触发下面的。

返回true,如果是子控件返回true,那么它的touch事件都在这里处理,父控件是处理不了,因为它收不到子控件传给他的touch,被子控件给拦截了。


那么首先看一下默认的触屏事件的在两个函数之间的传递流程。如下图:


如果仅仅想让MyTextView来响应触屏事件,让MyTextView的OnTouchEvent返回true,那么事件流就变成如下图,可以看到layoutview1,layoutview2已经不能进入OnTouchEvent:


另外一种情况,就是外围容器想独自处理触屏事件,那么就应该在相应的onInterceptTouchEvent函数中返回true,表示要截获触屏事件,比如layoutview1作截获处理,处理流变成如下图:


以此类推,我们可以得到各种具体的情况,整个layout的view类层次中都有机会截获,而且能看出来外围的容器view具有优先截获权。

ViewGroup里的onInterceptTouchEvent默认值是false这样才能把事件传给View里的onTouchEvent.

ViewGroup里的onTouchEvent默认值是false。

View里的onTouchEvent返回默认值是true.这样才能执行多次touch事件。(返回false,认为你没有消费,接下来其他事件都不在这里触发)

(注:可能你会觉得是否消费了有关系吗,反正我已经针对事件编写了处理代码(即你在那里写了代码处理这个事件,但是不算消费,还是会传递)?答案是有区别!比如ACTION_MOVE或者ACTION_UP发生的前提是一定曾经发生了ACTION_DOWN,如果你没有消费ACTION_DOWN,那么系统会认为ACTION_DOWN没有发生过,所以ACTION_MOVE或者ACTION_UP就不能被捕获。)(不消费不代表不处理


View的dispatchTouchEvent

View的onTouchEvent


一、onTouchEvent:

        onTouchEvent是在view中定义的一个方法。处理传递到view 的手势事件。手势事件类型包括ACTION_DOWN,ACTION_MOVE,ACTION_UP,ACTION_CANCEL四种事件。一旦onTouchEvent方法被调用,并返回true则这个手势事件就结束了,并不会向下传递到子控件。

二、onInterceptTouchEvent:

      onInterceptTouchEvent是在ViewGroup里面定义的。Android中的ViewGroup布局类都会继承此类的。onInterceptTouchEvent是用于拦截手势事件的,每个手势事件都会先调用onInterceptTouchEvent。

      onInterceptTouchEvent()用于处理事件并改变事件的传递方向。返回值为false时事件会传递给子控件的onInterceptTouchEvent();返回值为true时事件会传递给当前控件的onTouchEvent(),而不在传递给子控件。由于onInterceptTouchEvent()的机制比较复杂,所以我在网上查了一下,有一下几种:

   1.       down事件首先会传递到onInterceptTouchEvent()方法
    2.       如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return false,那么后续的move, up等事件将继续会先传递给该ViewGroup,之后才和down事件一样传递给最终的目标view的onTouchEvent()处理。
    3.       如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return true,那么后续的move, up等事件将不再传递给onInterceptTouchEvent(),而是和down事件一样传递给该ViewGroup的onTouchEvent()处理,注意,目标view将接收不到任何事件。
   4.       如果最终需要处理事件的view的onTouchEvent()返回了false,那么该事件将被传递至其上一层次的view的onTouchEvent()处理。
   5.       如果最终需要处理事件的view 的onTouchEvent()返回了true,那么后续事件将可以继续传递给该view的onTouchEvent()处理。


下面在分析一下事件分发的机制,分发机制是由上往下的。有这样一个方法dispatchTouchEvent,该方法用来进行事件的分发,即无论ViewGroup或者View的事件,都是从这个方法开始的。然后就会执行上面的操作,直到这个事件被消耗。通过源代码的分析,大体是这样的:如果一个事件传递到了ViewGroup处,首先会判断当前ViewGroup是否要拦截事件,即调用onInterceptTouchEvent()方法;如果返回true,则表示ViewGroup拦截事件,那么ViewGroup就会调用自身的onTouchEvent来处理事件;如果返回false,表示ViewGroup不拦截事件,此时事件会分发到它的子View处,即调用子View的dispatchTouchEvent方法,如此反复直到事件被消耗掉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值