目录:
一.事件分发中的 onTouch 和 onTouchEvent 有什么区别,又该如何使用?
1.onTouch方法:
- 是View的 OnTouchListener接口中定义的方法。
- 当一个View绑定了OnTouchLister后,当有touch事件触发时,就会调用onTouch方法。
2.onTouchEvent方法:
- 是override 覆盖Activity的方法。
- 当屏幕有touch事件时,此方法就会别调用。
3.touch事件的传递:
(PS:onTouch 优先于 onTouchEvent 执行,两者都能得到事件内容(下,移动,弹起))
- 1.Activity有放一个TextView的实例tv,触摸时首先是tv响应touch事件,执行onTouch方法
2.如果onTouch返回值为true,表示这个touch事件被onTouch方法处理完毕,不会把touch事件再传递给Activity,onTouchEvent方法不会被调用。
3.返回false,表示这个touch事件没有被tv完全处理,onTouch返回以后,touch事件被传递给Activity,onTouchEvent方法被调用。
4.这两个方法都是在 View 的 dispatchTouchEvent 中调用.
5.控件必须是enable的,否则onTouch事件将永远得不到执行。
二.请描述一下 Android 的事件分发机制
主角:主要有两个:ViewGroup 和 View。
Activity 的 Touch事件事实上是调用它内部的ViewGroup的Touch事件.
View 在ViewGroup内,ViewGroup 也可以在其他ViewGroup内,这时候把内部的ViewGroup当成View 来
分析。先分析ViewGroup 的处理流程:首先得有个结构模型概念:ViewGroup和View组成了一棵树形结构,最顶层为 Activity 的 ViewGroup,如图:
当一个 Touch 事件(触摸事件为例)到达根节点,即Acitivty 的ViewGroup 时,它会依次下发,下发的过程是调用子View(ViewGroup)的dispatchTouchEvent方法实现的。
- 简单来说,就是ViewGroup遍历它包含着的子View,调用每个 View 的 dispatchTouchEvent 方法.
- 而当子 View 为 ViewGroup 时,又会通过调用 ViwGroup 的dispatchTouchEvent方法继续调用其内部的View 的dispatchTouchEvent方法。
- 上述例子中的消息下发顺序是: ①-②-⑥-⑦-⑧-③-④-⑤
- 如果⑥的dispatchTouchEvent返回结果为true,那么⑥-⑦-③-④将都接收不到本次Touch事件。
- (PS:一般默认是false不操作这个分发的方法)
关于Down,Move,Up:
- 1.触摸事件由Action_Down、Action_Move、Aciton_UP 组成,其中一次完整的触摸事件中,Down和Up 都只有一个,Move有若干个,可以为0个。
2.当Acitivty 接收到 Touch事件时,将遍历子 View 进行 Down 事件的分发。ViewGroup 的遍历可以看成是递归的。分发的目的是为了找到真正要处理本次完整触摸事件的 View。
3.当某个子View 的onTouchEvent()返回true时,会中止Down 事件的分发,同时在ViewGroup中记录该子View。接下去的Move和Up 事件将由该子View 直接进行处理。
4.由于子View 是保存在ViewGroup中的,多层ViewGroup的节点结构时,上级ViewGroup保存的会是真实处理事件的View所在的ViewGroup对象:如ViewGroup0-ViewGroup1-TextView的结构中,TextView 返回了 true,它将被保存在 ViewGroup1 中,而 ViewGroup1 也会返回 true,被保存在ViewGroup0中。当Move和UP事件来时,会先从ViewGroup0传递至ViewGroup1,再由ViewGroup1 传递至TextView。
6.当ViewGroup 中所有子View 都不捕获Down 事件时,将触发ViewGroup自身的onTouch事件。触发的方式是调用super.dispatchTouchEvent函数,即父类View 的dispatchTouchEvent方法。在所有子View 都不处理的情况下,触发Acitivity的onTouchEvent方法。
7.onInterceptTouchEvent有两个作用:
- 1.拦截Down 事件的分发。
- 2.中止Up 和Move事件向目标View 传递,使得目标View所在的ViewGroup捕获Up和Move事件。
三.代码演示
布局代码如下:
效果图:
三个代码都写onTouch方法
各自点击内,中外,效果图如下:
分别各自测试逐个设置消费的情况(观察打印才次数,摁下和弹起),打印的效果:
得出结论一:
- 然后重写方法:
- 布局重写分发方法和拦截方法
- view重写分发方法
然后再分别测试他们的传递过程: