android 事件传递 有哪几种方法,【图解】Android View 事件传递机制

MotionEvent — 点击事件

所有 Touch 事件都被封装成了 MotionEvent 对象,包括 Touch 的位置、时间、历史记录以及第几个手指(多指触摸)等。

当一个 MotionEvent 产生后,系统需要把这个事件传递给一个具体的View,而这个传递的过程就是分发过程。

事件类型

ACTION_DOWN : 手指刚接触屏幕

ACTION_MOVE : 手指在屏幕上移动

ACTION_UP : 手指从屏幕上松开的一瞬间

ACTION_POINTER_DOWN : (屏幕上已有触控点,再按下其他触控点)

ACTION_POINTER_UP :(屏幕上当前有多个触控点,松开非最后一个点)

ACTION_CANCEL :

每个事件都是以 ACTION_DOWN 开始 ACTION_UP 结束。

事件处理传递 —— dispatchTouchEvent() 函数拦截 —— onInterceptTouchEvent() 函数消费 —— onTouchEvent() 函数 和 OnTouchListener

处理事件的方法介绍:

dispatchTouchEvent(MotionEvent ev)

用来进行事件的分发。如果事件能够传递给当前 View,那么此方法一定会被调用,返回结果受当前 View 的 onTouchEvent() 和下级 View 的 dispatchTouchEvent()方法影响,表示是否消耗当前事件。

onInterceptTouchEvent(MotionEvent event)

在上述方法( dispatchTouchEvent() )的内部调用,用来判断是否拦截某个事件,如果当前 View 拦截了某个事件,那么在同一个事件序列当中,此方法不会被再次调用,返回结果表示是否拦截当前事件。

onTouchEvent(MotionEvent event)

在 dispatchTouchEvent 方法中调用,用来处理点击事件,返回结果表示是否消耗当前事件,如果不消耗,则在同一个事件序列中,当前View无法再次接受到事件。

传递流程

Activity ——> ViewGroup (父View) ——> View (子View,即目标View)

一图胜千言

(1) View 不处理事件流程图

17046840229e64b26cb1ce17d932762a.png

(2) View 处理事件流程图

cf079e98c46d034cf7765ac415f8a008.png

(3) View 事件被拦截的情况:

7109fee0d5be643df1e70f18a76f26ff.png

下面开始详解:

9a3b2cb978bb57ea56dc1d2d1784dd12.png触摸事件是一连串ACTION_DOWN,ACTION_MOVE..MOVE…MOVE、最后ACTION_UP,触摸事件还有ACTION_CANCEL事件。

事件都是从ACTION_DOWN开始的,Activity的dispatchTouchEvent()首先接收到ACTION_DOWN,执行super.dispatchTouchEvent(ev),事件向下分发。

dispatchTouchEvent()返回true,后续事件(ACTION_MOVE、ACTION_UP)会再传递,如果返回false,dispatchTouchEvent()就接收不到ACTION_UP、ACTION_MOVE。

情形 1 :ACTION_DOWN 事件没有被消费 流程图:

d04b4c73cc15d1c50857b93590580335.png

情形 2 :ACTION_DOWN 被目标 View 消费:

ef793fa20b374d745beed3235578043d.png

情形 2.1 后续ACTION_MOVE和UP在不被拦截的情况下都会去找VIEW

9026e552c86e9ea13a15260e68984a33.png

情形 2.2 后续的事件(ACTION_MOVE和UP)被拦截了

4e5aaec1e145bf0460c7c9881ab8a97c.png

情形 3 ACTION_DOWN一开始就被父View(ViewGroup)拦截

911a11caecdebe2e3074a8fea30d32fb.png

android中的Touch事件都是从ACTION_DOWN开始的:单手指操作:ACTION_DOWN—ACTION_MOVE—-ACTION_UP

多手指操作:ACTION_DOWN—ACTION_POINTER_DOWN—ACTION_MOVE–ACTION_POINTER_UP—ACTION_UP.

总结:事件从 Activity.dispatchTouchEvent()开始传递,只要没有被停止或拦截,从最上层的 View(ViewGroup)开始一直往下(子 View)传递。子 View 可以通过 onTouchEvent()对事件进行处理。

事件由父 View(ViewGroup)传递给子 View,ViewGroup 可以通过 onInterceptTouchEvent()对事件做拦截,停止其往下传递。

如果事件从上往下传递过程中一直没有被停止,且最底层子 View 没有消费事件,事件会反向往上传递,这时父 View(ViewGroup)可以进行消费,如果还是没有被消费的话,最后会到 Activity 的 onTouchEvent()函数。

如果 View 没有对 ACTION_DOWN 进行消费,之后的其他事件不会传递过来。

OnTouchListener 优先于 onTouchEvent()对事件进行消费。

上面的消费即表示相应函数返回值为 true。

参考博文:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值