Android Touch事件传递机制

传递Touch事件

Touch事件是由Linux内核的一个Input子系统来管理的(InputManager),Linux子系统会在 /dev/input/ 这个路径下创建硬件输入设备节点(这里的硬件设备就是我们的触摸屏了)。当手指触动触摸屏时,硬件设备通过设备节点向内核(其实是InputManager管理)报告事件,InputManager 经过处理将此事件传给 Android系统的一个系统Service: WindowManagerService 。

Touch 事件传递的基本的规则:

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()处理。

示例图解释 touch 时间传递过程:

这里写图片描述

Case 0 : onInterceptTouchEvent()处理down事件均返回false,onTouchEvent()处理事件均返回true

04-06 02:28:38.085 19815-19815/com.owenchan D/ParentLayout: [onInterceptTouchEvent] -> ACTION_DOWN

04-06 02:28:38.085 19815-19815/com.owenchan D/ChildLayout: [onInterceptTouchEvent] -> ACTION_DOWN

04-06 02:28:38.085 19815-19815/com.owenchan D/MyTextView: [onTouchEvent] -> ACTION_DOWN

04-06 02:28:38.227 19815-19815/com.owenchan D/ParentLayout: [onInterceptTouchEvent] -> ACTION_MOVE

04-06 02:28:38.227 19815-19815/com.owenchan D/ChildLayout: [onInterceptTouchEvent] -> ACTION_MOVE

04-06 02:28:38.228 19815-19815/com.owenchan D/MyTextView: [onTouchEvent] -> ACTION_MOVE

......

......    //省略过多的ACTION_MOVE

......

04-06 02:28:38.654 19815-19815/com.owenchan D/ParentLayout: [onInterceptTouchEvent] -> ACTION_UP

04-06 02:28:38.654 19815-19815/com.owenchan D/ChildLayout: [onInterceptTouchEvent] -> ACTION_UP

04-06 02:28:38.654 19815-19815/com.owenchan D/MyTextView: [onTouchEvent] -> ACTION_UP

onInterceptTouchEvent并没有做任何改变事件传递时序的操作,效果上和没有覆写该方法是一样的。可以看到,各种事件的传递本身是自底向上的,次序是:ParentLayout->ChildLayout->MyTextView。注意,在onInterceptTouchEvent均返回false时,ParentLayout和ChildLayout的onTouchEvent并不会收到事件,而是最终传递给了MyTextView。

Case 1: ParentLayout的onInterceptTouchEvent()处理down事件返回true,MyTextView的onTouchEvent()处理事件返回true

04-06 02:39:25.878 28073-28073/com.owenchan D/ParentLayout: [onInterceptTouchEvent] -> ACTION_DOWN

04-06 02:39:25.878 28073-28073/com.owenchan D/ParentLayout: [onTouchEvent] -> ACTION_DOWN

04-06 02:39:26.092 28073-28073/com.owenchan D/ParentLayout: [onTouchEvent] -> ACTION_MOVE

......

......//省略过多的ACTION_MOVE

......

04-06 02:39:26.403 28073-28073/com.owenchan D/ParentLayout: [onTouchEvent] -> ACTION_UP

由于ParentLayout在拦截第一次down事件时return true,所以后续的事件(包括第一次的down)将由ParentLayout 本身的onTouchEvent 处理,事件不再传递下去。

Case 2 ParentLayout,ChildLayout的onInterceptTouchEvent()处理down事件返回false,MyTextView的onTouchEvent()处理事件返回false
ChildLayout的onTouchEvent()处理事件返回true

04-06 02:54:03.557 8333-8333/com.owenchan D/ParentLayout: [onInterceptTouchEvent] -> ACTION_DOWN

04-06 02:54:03.557 8333-8333/com.owenchan D/ChildLayout: [onInterceptTouchEvent] -> ACTION_DOWN

04-06 02:54:03.557 8333-8333/com.owenchan D/MyTextView: [onTouchEvent] -> ACTION_DOWN

04-06 02:54:03.558 8333-8333/com.owenchan D/ChildLayout: [onTouchEvent] -> ACTION_DOWN

04-06 02:54:03.855 8333-8333/com.owenchan D/ParentLayout: [onInterceptTouchEvent] -> ACTION_MOVE

04-06 02:54:03.855 8333-8333/com.owenchan D/ChildLayout: [onTouchEvent] -> ACTION_MOVE

04-06 02:54:03.856 8333-8333/com.owenchan D/ParentLayout: [onInterceptTouchEvent] -> ACTION_MOVE

04-06 02:54:03.856 8333-8333/com.owenchan D/ChildLayout: [onTouchEvent] -> ACTION_MOVE

04-06 02:54:03.996 8333-8333/com.owenchan D/ParentLayout: [onInterceptTouchEvent] -> ACTION_UP

04-06 02:54:03.996 8333-8333/com.owenchan D/ChildLayout: [onTouchEvent] -> ACTION_UP

可以看到,由于MyTextView在onTouchEvent()中return false,down事件被传递给其父view,即LayoutView2的onTouchEvent()方法处理,由于在LayoutView2的onTouchEvent()中return true,所以down事件传递并没有上传到LayoutView1。注意,后续的move和up事件均被传递给LayoutView2的onTouchEvent()处理,而没有传递给MyTextView。

Demo代码地址 :https://github.com/chenzongwen/AndroidTouchDemo.git

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值