Android Touch事件传递机制

简介:

  Touch事件的传递机制与生活贴近,从父布局开始一步一步的向下分发事件。分发事件时调用boolean dispatchTouchEvent(MotionEvent ev);方法。此方法一般不重写它。而直到莫一个控件能够完成此事件时,调用boolean onTouchEvent(MotionEvent event)方法,即可结束。如果直到醉下层的一个view都没发处理这个,就会往父布局回传,依次调用boolean onTouchEvent(MotionEvent event)方法,直到回到最顶层的布局。   Touch事件传递时,每次分发之后,会调用拦截方法boolean onInterceptTouchEvent(MotionEvent ev)方法,拦截后由拦截者来执行。   Touch事件传递拥有记忆功能,处理了一次事件传递,假定底层布局都没发完成事件,最后是由顶层父布局自己处理的。那么,相同事件再次产生的时候,顶层布局就不会向下分配,而是自己直接处理事件。值得注意的是这个记忆只会在一系列事件完成之前有效,也就是从ACTION_DOWN事件开始,直到后续事件 ACTION_MOVE,ACTION_UP结束后,“记忆”的信息就会清除。

生活例子:

话说一家软件公司,来一个任务,分派给了开发经理去完成: 开发经理拿到,看了一下,感觉好简单,于是 开发经理:分派给了开发组长 开发组长:分派给了自己组员(程序员) 程序员:分派给了自己带的实习生。 实习生:好苦逼,无法分派,怎么办啊?只能自己干了 但是实习生能不能做好,有两种情况了。

情景一:

  实习生:经过一段时间的研究,琢磨,熬夜,奋斗,死敲,皇天不负有心人啊,完成了。   后来又来一个类似的任务,也按着这样传递下去了(开发经理->开发组长->程序员->实习生),又有实习生完成了。

情况二:

  实习生:经过一段时间的研究,琢磨,就是毫无头绪,无法完成,只能求教师傅(程序员)了。   程序员:啊,我怎么没留意就给实习生搞了,这任务好难啊,自己研究下,也没有头绪,没办法只能请求组长了。   开发组长:这任务不难啊,怎么我底下的人都不会了,没办法,只能自己搞了,经过,一段时间,完成了,感想,以后要是又有跟这个很类似的任务,我就自己弄了,不给他们弄了。   后来又来一个类似的任务,传递是这样的: 开发经理:分派给开发组长 开发组长:啊,又是跟着上一个很类似的任务,我自己弄吧,没过多久也完成了!

总结:

  可以看出这个公司的小例子正好对应了Touch事件传递机制。一层一层往下传递,当下面无法完成时,又网上回传。而当同样事件出现时,同样展现了他的记忆功能,不需要往下传递做重复的事情,直接由上次做了这个事件的人直接处理。

程序例子:

  首先创建四个类,分配继承Activity,FrameLayout,LinearLaytou,TextView。然后分别重写分发、拦截、处理方法,打印Log信息。这里的Activity可以看做开发经理,FrameLayout是开发组长,LinearLayout是程序员,TextView是实习生。

情景一:

  我们将TextView的onTouchEvent返回值设置为true即实习生成功处理了问题。点击蓝色区域,那么应该发生的传递机制为任务一级一级的传下来,TextView(实习生)之后,任务被完成了。当再遇到相同的任务时,任务还是会被一级一级的传下来,最后由TextView(实习生)解决。

  此图是对蓝色区域完成了一次点击(按下、抬起)后产生的log信息。可以看出父布局依次执行分发和拦截方法,任务一级一级的被传递到了作为没有子布局的TextView上。而TextView因为返回值设置为ture,代表解决了问题,任务结束。   而手指抬起时再次发生了Touch事件,任然传递至TextView被解决。

情景二:

  我们将TextView的onTouchEvent方法设置为false(代表实习生不能解决),而将FrameLayout的onTouchEvent方法设置为true(代表开发组长能解决)。同样点击蓝色区域,那么传递的方式应该是先一级一级的分发给下属处理,到了TextView(实习生)后,没有下属了,他又处理不了,就往上回传递,知道传递到FrameLayout(开发组长)后,他将任务处理了。任务结束。   第二次类似的任务来了,Activity(开发经理)将任务同样的分发下去,FrameLayout(开发组长)接到任务后,发现是跟上次相似的任务,下面的又不会,直接就自己解决了。这里体现出了Touch时间传递机制的记忆性。

  此图是点击蓝色区域后log打印出的信息,值得注意的是,当FrameLayout按照传递的记忆性直接执行完成任务时,是不会触发拦截方法的。

情景三:   当拦截方法进行拦截时(即拦截方法返回值为true),任务即为拦截者进行处理,若无法处理,直接往上级回传。

  此图为LinearLayout(程序员)进行了拦截,然后开始处理,但是发现处理不了, 然后就直接往上传递,被FrameLayout(开发组长)处理了。然后相似的任务来时,FrameLayout(开发组长)直接就处理了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏小巫技术博客

Android触摸事件机制

1113
来自专栏源哥的专栏

SaaS行业命名规范

    很多企业在启动软件开发的时候,完成没有命名规范,导致代码的可读性极差。而业界对于命名,却没有一个统一的命名规范,比如说,获取客户列表,Java类的方法是...

1653
来自专栏葬爱家族

Android高德之旅(1)基础地图

这个系列之前在CSDN上就发了,不过刚开始就因为公司项目忙搁置了,现在转移阵地到简书,希望这次能坚持把这个系列做完。

1022
来自专栏Jerry的SAP技术分享

在微信小程序里自动获得当前手机所在的经纬度并转换成地址

return axios.post('https://restapi.amap.com/v3/geocode/regeo?key=' + key + locat...

4181
来自专栏Flutter入门到实战

Android适配全面总结(三)----ROM适配

版权声明:本文为博主原创文章(部分引用他人博文,已加上引用说明),未经博主允许不得转载。https://www.jianshu.com/p/f9c67a4b90...

2811
来自专栏Android 技术栈

Android 阿里百川cps SDK接入流程

因公司业务需求,需接入阿里百川SDK和京东联盟cps相关服务,为了跳到淘宝和京东,用户购买后得到佣金。接入过程中遇到很多坑,网上相关资料也甚少,虽然东西不算多,...

2661
来自专栏小文博客

良心压缩软件Bandizip——无广告超精简

6.4K5
来自专栏图像识别与深度学习

《Android》Lesson09-Acitivity的四种启动模式

15410
来自专栏图像识别与深度学习

《Android》Lesson24-综合项目实战

2278
来自专栏图像识别与深度学习

《Android》Lesson16-Fragment

1646

扫码关注云+社区

领取腾讯云代金券