Touch事件传递机制解析

涉及的知识点:

主要涉及的方法:

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

拥有这三个方法的类:

类型 相关类 方法
Activity类 Activity dispatchTouchEvent(); 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)
Touch事件传递机制解析_第1张图片

分析

分发过程中,所有组件都不会处理事件,且事件并不会被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)
Touch事件传递机制解析_第2张图片

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

(注:logout中的Main表示Activity)

Touch事件传递机制解析_第3张图片

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

点击ViewC, 只在ViewA中对事件下发过程进行拦截onInterceptTouchEvent{…..return true;},并且ViewA中的onTouchEvent不处理事件(return false),事件回传
Touch事件传递机制解析_第4张图片

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

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

Touch事件传递机制解析_第5张图片
(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;}

Touch事件传递机制解析_第6张图片

你可能感兴趣的:(安卓学习笔记)