"Android Touch事件分发机制"-Android面试必问"精华技能点"汇总

本文详细解释了Android中onTouch和onTouchEvent的区别及其使用场景,并深入探讨了Android的事件分发机制,包括ViewGroup和View的角色及Down、Move、Up事件的处理流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录:

一.事件分发中的 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重写分发方法
      这里写图片描述

然后再分别测试他们的传递过程:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值