Touch事件传递机制解析

涉及的知识点:

主要涉及的方法:

方法用途
public boolean dispatchTouchEvent(MotionEvent ev)用来分发TouchEvent
public boolean onInterceptTouchEvent(MotionEvent ev)用来拦截TouchEvent
public boolean onTouchEvent(MotionEvent ev)用来处理TouchEvent

拥有这三个方法的类:

类型相关类方法
Activity类ActivitydispatchTouchEvent(); onTouchEvent();
View容器(ViewGroup的子类)FrameLayout、LinearLayou、ListView、ScrollVIew…dispatchTouchEvent(); onInterceptTouchEvent(); onTouchEvent();
View控件(非ViewGroup子类)Button、TextView、EditText……dispatchTouchEvent(); onTouchEvent();

ViewGroup的dispatchTouchEvent是真正在执行“分发”工作,而View的dispatchTouchEvent方法,并不执行分发工作,或者说它分发的对象就是自己,决定是否把touch事件交给自己处理,而处理的方法,便是onTouchEvent事件

三个方法的具体作用:

方法用途
dispatchTouchEvent()用来分派事件。其中调用了onInterceptTouchEvent()和onTouchEvent(),一般不重写该方法
onInterceptTouchEvent()用来拦截事件。ViewGroup默认为(return false)表示不对事件进行拦截,事件将向下传递(传递给其子View);若手动重写该方法,使其返回true则表示拦截,事件将终止向下传递,则事件将由当前ViewGroup类(onTouchEvent)来处理
onTouchEvent()用来处理事件。返回true则表示该View能处理该事件,事件将终止向上传递(传递给其父View);返回false表示不能处理,则把事件传递给其父View的onTouchEvent()方法来处理

三个方法并不总是同时存在的

无拦截的touch事件处理过程

流程图

(视图嵌套关系 Activity–>out–>middle–>center,点击center)
这里写图片描述

分析

分发过程中,所有组件都不会处理事件,且事件并不会被center的onTouchEvent方法“消费”(ruturn false),则事件会层层逆向传递回到Activity。对于后续的move、up事件,由于第一个down事件已经确定由Activity处理事件,故up事件由Activity的dispatchTouchEvent直接分发给自己的onTouchEvent方法处理。
即,onInterceptTouchEvent()来决定是否将事件传递给子View处理,onTouchEvent()用来对具体事件的处理(对一些功能的实现)并且决定了是否将处理事件的能力返回给父View.

实例分析

一次点击(抬起)操作,当前的activity分别会响应一次ActionDown,n次ActionMove(n>=0),1次ActionUp事件

Demo示图

例. 视图嵌套 Activity–>ViewA–>ViewB–>ViewC(其中ViewA、ViewB继承至FrameLayout,ViewC继承自View)
这里写图片描述

情况一(点击ViewC,过程中无任何拦截)

(注:logout中的Main表示Activity)

这里写图片描述

情况二(点击ViewC,过程中存在拦截操作)

点击ViewC, 只在ViewA中对事件下发过程进行拦截onInterceptTouchEvent{…..return true;},并且ViewA中的onTouchEvent不处理事件(return false),事件回传
这里写图片描述

情况三(点击ViewB, 对事件回传过程进行截获)

只在ViewA中对事件回传过程进行截获onTouchEvent{…..return true;}

这里写图片描述
(ActionDown结束后,后续的事件(Move、Up)传递过程中,只有被确定处理该touch事件的view才进行onTouchEvent方法的响应)
说明:一次完整的Touch事件,应该是由一个Down、一个Up和若干个Move组成的。Down方式通过dispatchTouchEvent分发,分发的目的是为了找到真正需要处理完整Touch请求的View。当某个View或者ViewGroup的onTouchEvent事件返回true时,便表示它是真正要处理这次请求的View,之后的Aciton_UP和Action_MOVE将由它处理。当所有子View的onTouchEvent都返回false时,这次的Touch请求就由根ViewGroup,即Activity自己处理了。

情况四(点击ViewC, 对事件分发过程进行拦截):

在ViewB中对事件分发过程进行拦截dispatchTouchEvent{…..return true;}

这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值