android 事件传递机制

Android里面事件传递机制还是非常重要的。

 

下面记录一下Touch事件:

涉及Activity 、View 、ViewGroup

 

 

Touch 事件相关方法

方法功能

ViewGroup  

View      

Activity    

dispatchTouchEvent(MotionEvent ev)

事件分发

 

Yes

Yes

Yes

onInterceptTouchEvent(MotionEvent ev)

事件拦截

 

Yes

No

No

onTouchEvent(MotionEvent ev)

事件处理

yes

yes

yes

 

 

用代码来测试:



如上图,有三个控件,最外侧是LinearLayout、第二层也是LinearLayout,里面是一个View

 

 

Touch事件传递,Activity----》MyLinearLayout1----》MyLinearLayout2----》MyView

下面我用图来描述事件传递的过程。

 

红色表示返回值为true,蓝色表示返回值为false




小结:

·        Android中事件传递按照从上到下进行层级传递,事件处理从Activity开始到ViewGroup再到View

·        事件传递方法包括dispatchTouchEventonTouchEventonInterceptTouchEvent,其中前两个是ViewViewGroup都有的,最后一个是只有ViewGroup才有的方法。这三个方法的作用分别是负责事件分发、事件处理、事件拦截。

·        onTouch事件要先于onClick事件执行,onTouch在事件分发方法dispatchTouchEvent中调用,而onClick在事件处理方法onTouchEvent中被调用,onTouchEvent要后于dispatchTouchEvent方法的调用。

·        Touch事件里面有downmoveup三种事件。先传入down事件,如果我们的界面上的所有地方都没有消费掉这个down事件,那么android系统就会认为我们的界面上不需要处理Touch事件,那么后面的moveup事件都不会再传入进来。(非常重要)

android 事件传递机制_第1张图片

上图是我们的测试日志,里面的数字0表示Down事件。

MyLinearLayout1 MyLinearLayout2MyView我都没有处理Touch事件。从上图可以看出根本就没有Move2)、UP1)的事件。


概念的东西先就说这么多,下面说一个我遇到的例子:

了解了这些之后,我们就可以在做项目的时候更好的利用事件传递机制了。比如最近项目里面有一个需求是,在一个播放pdf或视频的界面,如果用户一分钟没有操作屏幕上面的任何东西就要暂停播放,并且弹出对话框询问用户是否离开。用户点击对话框上的“我在的”按钮,就dismiss对话框继续播放。(想出这个需求的人真是TM的淫才,纯粹没事找事干)。

要实现这个功能笨一点的方法是在界面上的每个控件上都注册onTouch事件或者onClick事件。界面简单的话,这个方法是可以的。但是要是界面上有十几二十个控件怎么办呢

现在了解了android的事件传递机制就简单了。

最牛逼彻底的方法是:在 Activity dispatchTouchEvent 方法中处理。这是事件最先到达的地方,之后才会传到 Window 里面,再然后才到界面的布局中。

这样写又方便又维护简单。


测试代码地址



你可能感兴趣的:(android 事件传递机制)