时间:2021-05-19
开头说说初衷
网上关于点击事件分发的文章一搜一大堆,标题一看,不是“30分钟让你弄明白XXX”就是“这是讲解XXX最好的文章”,满怀憧憬与信心,忍不住兴奋的点进去一看,发现不是代码就全是图,我基本上看完了所有相关的文章,结果硬是看了三个小时也没搞懂。所以最后还是决定自己去试一试,看一看点击事件分发到底是怎么个流程,我写的肯定不会比其他文章好多少,但是呢,带着一个初学者的心,去分析这个东西,自己能弄明白的同时,也让想学习这个的人看了之后有些许收获,那就足够了。
运行的环境
所有的源码都基于API 26,也就是Android8.0奥利奥,Android Studio 3.0.1,想要自己敲代码试试的同学可以参考一下
进入正题
分析点击事件分发流程,是想弄明白当我们用手指去点击屏幕的时候,分为三个动作,按下,移动和抬起,屏幕上的东西是怎么知道我们点了它的,在这中间到底经历了什么。所以要先来模拟一下这个点击的过程,看看到底调用了哪些方法。
搭建最简单的结构
新建Activity,重写dispatchTouchEvent和onTouchEvent,前面的方法负责点击事件的分发,后面的方法负责点击事件的消耗,然后打印三种触摸事件的触发
新建一个类继承自LinearLayout,同样也重写dispatchTouchEvent和onTouchEvent,还有因为LinearLayout继承自ViewGroup,ViewGroup是可以拦截点击事件的,这个很好理解,因为控件都是放在他里面的嘛。所以还要重写onInterceptTouchEvent方法
(这里有个重点).
这里有个需要注意的地方就是Android的控件有些是默认可以点击的(如Button),还有一些是默认不可点击的(如TextView)他们的分发是有一些不同的,这里我们先看不可点击的,新建一个类继承android.support.v7.widget.AppCompatTextView,兼容的TextView,同时跟Activity一样重写dispatchTouchEvent和onTouchEvent,代码不贴了,跟上面一样,它是普通控件,没有拦截的方法。
开始点击,移动手指后抬起
然后来点一点屏幕上的控件看看打印的log,dispatchTouchEvent和onTouchEvent都返回默认的实现super,onInterceptTouchEvent默认返回false,表示不拦截,默认的情况打印:
1.--------------------------------------D/MainActivity: Activity dispatchTouchEvent ACTION_DOWND/MyLayout: dispatchTouchEvent ACTION_DOWND/MyLayout: onInterceptTouchEvent ACTION_DOWND/MyTextView: dispatchTouchEvent ACTION_DOWN2.--------------------------------------D/MyTextView: onTouchEvent ACTION_DOWND/MyLayout: onTouchEvent ACTION_DOWND/MainActivity: Activity onTouchEvent ACTION_DOWN3.--------------------------------------D/MainActivity: Activity dispatchTouchEvent ACTION_MOVED/MainActivity: Activity onTouchEvent ACTION_MOVED/MainActivity: Activity dispatchTouchEvent ACTION_MOVED/MainActivity: Activity onTouchEvent ACTION_MOVED/MainActivity: Activity dispatchTouchEvent ACTION_UPD/MainActivity: Activity onTouchEvent ACTION_UP这是默认的情况,把它分为三个阶段:
1. 事件的分发,从上到下,从Activity到Layout到Text的dispatchTouchEvent结束
2. 事件的消耗,从下到上,从Text到Layout到Activity的onTouchEvent结束
3. 这套动作的后续事件交给上个事件的最后消耗者,不经过其他控件的分发
三个函数的其他返回值
dispatchTouchEvent和onTouchEvent都有三种返回情况
- true
- false
- super.dispatchTouchEvent(ev)和super.onTouchEvent(event)
onInterceptTouchEvent有两种返回,true和false,这样来看, 组合起来真是情况太多了,写下来挨个分析看代码的话怕是要看晕,所以这里用一张图来看看所有的情况:
普通不可点击View的事件分发流程
默认可点击控件的事件分发
比如Button这种默认可以点击的控件,或者设置android:clickable=”true”的控件,在分发流程中有一些不同,主要是onTouchEvent的默认方法不同,它直接消耗点击事件,不再往上传递。
可点击View的事件分发流程
结语
事件的分发流程到此就结束了,目的已经达到了,找到了我们想要点击的那个按钮或者其他控件,总结下来就是从Activity经过ViewGroup然后到View依次分发,然后又从底向上确认自己是否消耗该事件,如果某个对象消耗了,动作的后续事件都由他来处理。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
前言上一篇讲了Android触摸事件的传递机制,具体可以看这里初识Android触摸事件传递机制。既然知道Android中触摸事件的传递分发,那么它能解决什么样
事件分发是Android中非常重要的机制,是用户与界面交互的基础。这篇文章将通过示例打印出的Log,绘制出事件分发的流程图,让大家更容易的去理解Android的
关于Android的TouchEvent事件分发机制可以看这里:Java_Android_Learn,本文讲解的是如何去解决View之间的滑动冲突当父容器与子V
下文我们介绍两种双击事件拦截的方式1.通过Android的事件分发机制进行拦截(dispatchTouchEvent)话不多说,直接上代码:/**判断是否是快速
Android手势事件的冲突跟点击事件的分发过程息息相关,由三个重要的方法来共同完成,分别是:dispatchTouchEvent、onInterceptTou