android touch事件流程分析

本文详细解析了Android中Touch事件的处理流程,包括Activity、ViewGroup和View三个层面的事件分发与处理机制,并探讨了ACTION_DOWN、ACTION_MOVE及ACTION_UP等事件如何影响滑动过程。

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

这里我们先将可以接收并处理Touch的view分个类

首先是起点(activity),然后是Layout等ViewGroup的子类,而最后一类则是最小的图形容器view.

而我们要讨论的Touch处理函数总有三种:

DispatchTouchEvent(MotionEvent ev),

OninterceptTouchEvent(Motion ev),

OnTouchEvent(MotionEvent ev);

其中OnInterceptTouchEvent(MotionEvent ev) 仅ViewGroup有。其它的三类都有。

那么Touch事件从何处开始呢?我们声明使用的对象,都是层层继承的下的子类。比如继承自ViewGroup的LinearLayout,RelativeLayou等。我们直接调用的是它们的三种Touch处理函数。所以在继承的时候想要其往下继续处理,就一定要使用Super继承调用父类函数。

那么我们就按流程来分析吧。首先,Activity启动。创建了我们所看到的UI类。然后等待我们的交互。当我们触碰就激活了Touch事件。首先由Activity中的dispatchTouchEvent 来分发。如果是Activity的子类重写则一定要加上Super.dispatchTouchEvent(ev);否则无论返回的是true还是false.则没有函数来处理该事件,造成所有touch失效。

然后呢事情就交给ViewGroup处理了。


onInterceptTouchEvent 的父类返回是false ,所以一般是不会阻断的。

这里我们要特别补充一下滑到事件:滑到事件的组成为--ACTION_DOWN,ACTON_MOVE,ACTION_MOVE...ACTION_MOVE,ACTION_UP组成。

做为ViewGoup。OnInterceptTouchEvent是其第一个处理的函数。

然后呢,我们检测到ACTION_DOWN,然后交由OnInterceptTouchEvent处理,如果是true,则后面的ACTION_MOVE,ACTION_UP交由该VIewGoup的OnTouchEvent处理。

如果OnInterceptTouchEvent对ACTION_DOWN进行拦截,返回true,则交于子VIew处置,同样执行上面的判断,此时ViewGroup的OnInterceptTouchEvent会一直值被调用,用于传递Touch事件给子view。而子view对于滑动事件,先接收了ACTION_DOWN,当检测的手指偏移达到了ACTION_MOVE的滑动标准。此于应进行ev.getAction==MOTIONEVENT.ACTION_MOVE的判断,是的话返回true,进行拦截,此后的滑动事件将不经过该子View的onInterceptTouchEvent事件,全部交由基OnTouchEvent处理。

以下内容转自其它博客:如果在某个层级没有处理ACTION_DOWN事件,那么该层就再也收不到后续的Touch事件了直到下一次ACTION_DOWN事件。

    说明:a.某个层级没有处理某个事件指的是它以及它的子View都没有处理该事件。

    ViewGroup层处理Touch事件的总体逻辑是:先检测是否需要拦截,没有拦截的话下发给子View处理,如果子View没有处理再自行处理,自行处理的逻辑与View一样。

      拦截的逻辑是,将从down到up之间的所有事件看作一组事件,如果从down就拦截了,则组内的后续其它事件完全交给自己处理,不需要再进入拦截逻辑了;如果是从中间拦截,则先给子View发送cancel事件,组内的后续其它事件完全交给自己处理,不需要再进入拦截逻辑了。

      分发的逻辑是,在ACTION_DOWN事件的时候,寻找子View进行处理,称为寻找Target;如果没有找到Target,则自行处理;如果找到Target,则交由Target处理。

      从代码上看,dispatchTouchEvent负责分发逻辑,onTouchEvent负责真正的处理逻辑,一般应该重载onTouchEvent,只有特殊情况下才需要重载dispatchTouchEvent。



滑动流程:

OnIterceptOnTouchEvent 代号:void1

OnTouchEvent 代号:void2

当手指触摸屏幕时,这时将触发viewgroup的void1方法的ACTION_DOWN方法,返回值为false,

然后触发void1方法的ACTION_MOVE方法,这时会有一个计算判断,当手指的位置发生偏移时,

证明用户想滑动页面,这时return ture,将ACTION_MOVE这个动作传递给void2后续触摸事件将不会触发void1,

而void2根据左边来相应的进行绘图滑动。结束时触发void2的ACTION_UP动作,继而告诉系统触摸事件完成。



中途破坏了滑动事件的特殊情况:

如果一个非ACTION_DOWN事件被父View拦截了,则那些上次处理了ACTION_DOWN事件的子View会收到一个ACTION_CANCEL事件,之后不会再收到任何Touch事件了,即使父View不再拦截后续的Touch事件。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值