博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TouchEvent的传递过程学习笔记
阅读量:7232 次
发布时间:2019-06-29

本文共 3079 字,大约阅读时间需要 10 分钟。

hot3.png

在学习自定义控件时,发现SDK中对touch event的描述比较模糊,所以自己写了个demo并结合源代码测试了一下

在View类中,处理TouchEvent的方法有:dispatchTouchEvent和onTouchEvent

在ViewGroup类中处理TouchEvent的方法有:ViewGroup、onInterceptTouchEvent和onTouchEvent

测试布局模型是:

    

当点击View的时候

情况一:如果所有的处理函数都返回false,TouchEvent的传递路径是:

1) ViewGroup.dispatchTouchEvent-----------------ACTION_DOWN2) ViewGroup.onInterceptTouchEvent--------------ACTION_DOWN3) View.dispatchTouchEvent----------------------ACTION_DOWN4) View.onTouchEvent----------------------------ACTION_DOWN5) ViewGroup.onTouchEvent-----------------------ACTION_DOWN

而且只会受到ACTION_DOWN事件,不会收到ACTION_UP事件或者其它后续事件

情况二:MyView的onTouchEvent返回true,其它都返回false时,结果跟情况一一样

1) ViewGroup.dispatchTouchEvent-----------------ACTION_DOWN2) ViewGroup.onInterceptTouchEvent--------------ACTION_DOWN3) View.dispatchTouchEvent----------------------ACTION_DOWN4) View.onTouchEvent----------------------------ACTION_DOWN5) ViewGroup.onTouchEvent-----------------------ACTION_DOWN

情况三:MyView的onTouchEvent和dispatchTouchEvent都返回true,其它返回false

1) ViewGroup.dispatchTouchEvent-----------------ACTION_DOWN2) ViewGroup.onInterceptTouchEvent--------------ACTION_DOWN3) View.dispatchTouchEvent----------------------ACTION_DOWN4) View.onTouchEvent----------------------------ACTION_DOWN

你会发现ViewGroup的onTouchEvent不会收到消息,但是还是收不到ACTION_UP事件

情况四:MyView的onTouchEvent和dispatchTouchEvent都返回true,MyViewGroup的dispatchTouchEvent也返回true的时候:

1) ViewGroup.dispatchTouchEvent-----------------ACTION_DOWN2) ViewGroup.onInterceptTouchEvent--------------ACTION_DOWN3) View.dispatchTouchEvent----------------------ACTION_DOWN4) View.onTouchEvent----------------------------ACTION_DOWN1) ViewGroup.dispatchTouchEvent-----------------ACTION_UP2) ViewGroup.onInterceptTouchEvent--------------ACTION_UP3) View.dispatchTouchEvent----------------------ACTION_UP4) View.onTouchEvent----------------------------ACTION_UP

这时候就能收到ACTION_UP事件

ViewGroup dispatchTouchEvent(event)传递的主要逻辑的伪码:

private View mMotionTarget;//保存真正处理响应的Viewif (action == MotionEvent.ACTION_DOWN) //ACTION_DOWN事件{    if (mMotionTarget != null) {        mMotionTarget = null;    }    if (!onInterceptTouchEvent()){ //如果拦截方法返回false,即不拦截        for (allChild){ //循环所有子View或者ViewGroup            if (child.dispatchTouchEvent()){ //如果child的dispatchTouchEvent返回true,即处理了事件                mMotionTarget = child;                return true; //如果child处理的消息,则直接返回true            }        }    } else { //如果拦截方法返回true,即拦截此事件        不把此事件传递给child,即child将不会收到此事件    }}if (mMotionTarget == null){    //调用自己的onTouchEvent方法    //两种情况会走这个分支:1)ACTION_DOWN事件,child都返回false    //2)后续事件,并且之前的ACTION_DOWN事件,child都返回false    return onTouchEvent();}//以下是后续事件的处理过程if (onInterceptTouchEvent()){ //如果事件被拦截    mMotionTarget.dispatchTouchEvent(ACTION_CANCEL);//给目标child发送cancel事件    return true;//直接返回} else {//事件没有被拦截    return mMotionTarget.dispatchTouchEvent();//把事件交给child处理}

View的dispatchTouchEvent(event)伪码很简单:

return onTouchEvent();

由此可以看出,要想收到ACTION_DOWN的后续事件的条件是路径上的所有dispatchTouchEvent都得返回true

并且自己的onTouchEvent得返回true,而且路径上没有拦截器拦截事件

转载于:https://my.oschina.net/u/1459779/blog/208672

你可能感兴趣的文章
k8s与数据分析--利用redash做自助数据分析
查看>>
Alibaba Arthas 3.1.0版本:在线教程、内存编绎器和强大的自动补全
查看>>
CentOS服务器安装Telnet来远程连接服务器
查看>>
名称,决定了平台的发展愿景——互联网平台建设系列
查看>>
基于django的视频点播网站开发-step15-项目部署
查看>>
《从机器学习到深度学习》笔记(1)有监督学习
查看>>
冬季FEKKAI演绎时尚搭配
查看>>
部分 I. 教程_第 2 章 SQL语言_2.3. 创建一个新表
查看>>
spring boot redis 自定义序列化方式(fastJson)
查看>>
MeEdu 0.1.4 发布,基于 Laravel 开发的在线视频点播系统
查看>>
Centos-Mysql安装
查看>>
Tigase负载均衡策略
查看>>
属性通知之INotifyPropertyChanged
查看>>
Android圆形扩展动画
查看>>
Android开发之TabLayout实现顶部菜单
查看>>
如何解决Asp.Net MVC和WebAPI的Controller名称不能相同的问题
查看>>
实时计算Flink > 准备工作——角色授权
查看>>
开源大数据周刊-第105期
查看>>
Linux rsync传输(服务端和客户端)
查看>>
如何生成16位流水号
查看>>