WebView与ListView滑动冲突——(一)事件基础篇

Android中的事件有很多种,从宏观上来讲我们最常见,最常用的就是onClick事件了,微观上来说就是onTouchEvent、onInterceptTouchEvent、dispatchTouchEvent等方法都具有MotionEvent参数,该Event即为用户一次行为的具体体现。如果其中某一个方法返回true,则代表改方法消费了该事件,则该事件将不会向下传递,其后的ACTION_MOVE、ACTION_UP等事件都将会在这里进行处理,不会向下传递。

MotionEvent 常见事件:

常量解释
ACTION_DOWN表示用户开始触摸
ACTION_MOVE表示用户在移动
ACTION_UP表示用户抬起了手指
ACTION_CANCEL表示手势被取消了,不常见
ACTION_OUTSIDE表示用户触碰超出了正常的UI边界,不常见
ACTION_POINTER_DOWN有一个非主要的手指按下了(多点按下动作)
ACTION_POINTER_UP一个非主要的手指抬起来了(多点离开动作)

事件分发机制

Android的事件分发机制主要涉及到这三个方法:dispatchTouchEvent、onInterceptTouchEvent以及onTouchEvent

1.dispatchTouchEvent

处理触摸事件的分发,Android中的所有事件都必须经过这个方法的分发,然后决定是自身消费当前事件还是继续往下分发给子控件处理。

2.onInterceptTouchEvent

该方法只有在ViewGroup或其子类中才具有。作用是系统向该ViewGroup及其各个ChildView触发onTouchEvent方法之前对相关事件进行一次拦截。 ACTION_DOWN事件会首先传递到ViewGroup中的onInterceptTouchEvent方法中,下面分两种情况来说明一下该方法返回值的作用。
返回true

  • 如果onInterceptTouchEvent处理完ACTION_DOWN事件返回true,则系统不会将该ACTION_DOWN事件传到目标View中的onTouchEvent方法中,而且后续的ACTION_MOVE、ACTION_UP事件将不再调用该ViewGroup中的onInterceptTouchEvent方法,直接将这些事件传递给该ViewGroup中的onTouchEvent处理。

  • 如果onInterceptTouchEvent处理完ACTION_MOVE返回true,则系统不会将ACTION_MOVE事件传递到目标View中的onTouchEvent方法中,而是传递ACTION_CANCEL事件到目标View的onTouchEvent方法中,只传递一次,此后与目标View没有任何关系(包括最后的ACTION_UP事件),只调用ViewGroup中的onTouchEvent方法。

返回false

  • 如果onInterceptTouchEvent处理完ACTION_DOWN事件返回false,则系统还会将该ACTION_DOWN事件传到目标View当中,并且后续的ACTION_MOVE事件同样先传递到onInterceptTouchEvent中

  • 如果onInterceptTouchEvent处理完ACTION_MOVE返回false,则系统还会将ACTION_MOVE事件传递到目标View中的onTouchEvent方法中。

3.onTouchEvent

对于onTouchEvent也分两种情况来说明把,毕竟这种方法的返回值才是关键。
返回true

  • 如果View中的onTouchEvent返回true的话就表示该View消费了事件,进入不到ViewGroup的onTouchEvent中了

  • 如果ViewGrop的onTouchEvent返回true的话就表示该ViewGrop消费了事件,进入不到activity的onTouchEvent中了

返回false

  • View的onTouchEvent返回为false表示view处理完onTouchEvent后不消费这次事件,那么这个事件就会继续传递到他的上一层ViewGroup的onTouchEvent事件中

  • ViewGrop的onTouchEvent返回为false表示这个ViewGroup处理完onTouchEvent后不消费这次事件,这个事件就会继续传递到activity的onTouchEvent中

这里写图片描述

总之,如果最里层的返回false就会交给他的上一层处理,否则就会消费这次事件,停止向下传递

ViewGroup事件分发模型

想要搞清楚ViewGroup的事件分发机制,首先就得先在脑子中行程一种宏观上的事件模型,才能大致明白事件分发到底是个什么东西。如图:

这里写图片描述

我们就先通过ViewGroup的dispatchTouchEvent来了解一下事件分发模型。当一个Touch事件(触摸事件为例)到达根节点,即Acitivty的ViewGroup时,它会依次下发,下发的过程是调用子View(ViewGroup)的dispatchTouchEvent方法实现的。简单来说,就是ViewGroup遍历它包含着的子View,调用每个View的dispatchTouchEvent方法,而当子View为ViewGroup时,又会通过调用ViwGroup的dispatchTouchEvent方法继续调用其内部的View的dispatchTouchEvent方法。

上述例子中的消息下发顺序是这样的:①-②-③-⑤-⑥-⑦-④。dispatchTouchEvent方法只负责事件的分发,它拥有boolean类型的返回值,当返回为true时,顺序下发会中断。在上述例子中如果⑤的dispatchTouchEvent返回结果为true,那么⑥-⑦-④将都接收不到本次Touch事件。

图解事件分发

看到这相信你已经对事件分发有了大致的了解。下面通过几张图来学习一下dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent这三个方法和MotionEvent是怎么协同工作的。

ACTION_DOWN都未被消费

  • 都不拦截,ACTION_DOWN会依次向下传递
  • 都不消费,onTouchEvent会依次向上传递
  • 后续的ACTION_MOVE和ACTION_UP都不会在被传递
  • dispatchTouchEvent会返回false,表示事件未派发出去(未被消费)

这里写图片描述

ACTION_DOWN被View消费

  • ACTION_DOWN将不会向下传递

这里写图片描述

  • 之前消费了ACTION_DOWN事件,不管我后面消费不消费,ACTION_MOVE和ACTION_UP都会由我来处理(只要不被上层拦截)
  • 如果该View消费了ACTION_MOVE或ACTION_UP,则上层的dispatchTouchEvent将返回true,反之则返回false

这里写图片描述

ACTION_DOWN被View消费,上层拦截剩下事件

  • ACTION_DOWN被View消费后。上层的onInterceptTouchEvent返回true表示拦截事件

这里写图片描述

ACTION_DOWN直接被上层拦截

  • 一开始就被上层ViewGroup所拦截,并且消费了ACTION_DOWN事件,则后面的ACTION_MOVE和ACTION_UP都会被传递给他,不会向下传递给子View

这里写图片描述

注:Android中的Touch事件都是从ACTION_DOWN开始的

  • 单手指操作:ACTION_DOWN—ACTION_MOVE—-ACTION_UP
  • 多手指操作:ACTION_DOWN—ACTION_POINTER_DOWN—ACTION_MOVE–ACTION_POINTER_UP—ACTION_UP
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值