【朝花夕拾】Android自定义View篇之(五)Android事件分发机制(中)从源码分析事件分发逻辑及精彩遇到的一些“诡异”现象

前言

       在上一篇文章【【朝花夕拾】Android自定义View篇之(五)Android事件分发机制(上)Touch三个重要方法的处理逻辑】中,我们通过示例和log来分析了Android的事件分发机制。这些,我们只是看到了现象,如果要进一步了解事件分发机制,这是不够的,我们还需要透过现象看本质,去研究研究源码。本文将从源码(基于Android API-26)出发,去分析我们上一篇文章中看到的现象,以及其它一些和事件相关的常见问题,如requestDisallowInterceptTouchEvent为什么失效?view设置了focusable=“false”,为什么还能触发点击事件?Touch事件和Click事件谁先谁后?等等!

一、Activity对事件的处理逻辑

       在上一篇文章的代码示例中,我们的Boss——EventDemoActivity类中有如下代码

 1 //=============Boss:EventDemoActivity.java============
 2 @Override
 3     public boolean dispatchTouchEvent(MotionEvent ev) {
 4         Log.i("songzheweiwang", "[EventDemoActivity-->dispatchTouchEvent]ev=" + EventUtil.parseAction(ev.getAction()));
 5         return super.dispatchTouchEvent(ev);
 6     }
 7 
 8     @Override
 9     public boolean onTouchEvent(MotionEvent event) {
10         Log.i("songzheweiwang", "[EventDemoActivity-->onTouchEvent]event=" + EventUtil.parseAction(event.getAction()));
11         return super.onTouchEvent(event);
12     }

      Activity是事件的起点,dispatchTouchEvent又是整个逻辑中最早分发事件的地方。但是Activity并不是View体系中的一员,那它是怎样把事件分发到View体系中的呢?追踪super.dispatchTouchEvent方法,会进入到Activity.java中的方法

 //==========================Activity.java=======================
1
/** 2 * Called to process touch screen events. You can override this to 3 * intercept all touch screen events before they are dispatched to the 4 * window. Be sure to call this implementation for touch screen events 5 * that should be handled normally. 6 * 7 * @param ev The touch screen event. 8 * 9 * @return boolean Return true if this event was consumed. 10 */ 11 public boolean dispatchTouchEvent(MotionEvent ev) { 12 if (ev.getAction() == MotionEvent.ACTION_DOWN) { 13 onUserInteraction(); 14 } 15 if (getWindow().superDispatchTouchEvent(ev)) { 16 return true; 17 } 18 return onTouchEvent(ev); 19 }
 1 //=============Activity.java==========
 2 ......
 3 private Window mWindow;
 4 ......
 5 public Window getWindow() {
 6         return mWindow;
 7     }
 8 ......
 9 
10 //================Window.java================
11 /**
12  * ......
13  * <p>The only existing implementation of this abstract class is
14  * android.view.PhoneWindow, which you should instantiate when needing a
15  * Window.
16  */
17 public abstract class Window {
18   ......
19     public abstract boolean superDispatchTouchEvent(MotionEvent event);
20   ......
21 }
 1 //=============PhoneWindow.java==========
 2 ......
 3 // This is the top-level view of the window, containing the window decor.
 4 private DecorView mDecor;
 5 ......
 6 @Override
 7 public boolean superDispatchTouchEvent(MotionEvent event) {
 8     return mDecor.superDispatchTouchEvent(event);
 9 }
10 
11 //===========DecorView.java==========
12 ......
13 public boolean superDispatchTouchEvent(MotionEvent event) {
14     return super.dispatchTouchEvent(event);
15 }
16 ....
17 
18 //========ViewGroup.java=======
19 @Override
20 public boolean dispatchTouchEvent(MotionEvent ev) {
21 ......
22 }

猜你喜欢

转载自www.cnblogs.com/andy-songwei/p/11015293.html