面试之Android事件传递以上是测试结构；
firstl = this.findViewById(R.id.firstlinearLayout); secl = this.findViewById(R.id.seclinearLayout); testtv = this.findViewById(R.id.textView); firstl.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { Log.d(TAG, "MeLinearLayout OnTouchListener eventtype = "+event.getAction()); return false; } }); secl.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { Log.d(TAG, "SonLinearLayout OnTouchListener eventtype = "+event.getAction()); //return false; return true; } }); testtv.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { Log.d(TAG, "SonTextView OnTouchListener eventtype = "+event.getAction()); return false; } });
MeLinearLayout extends LinearLayout;
SonLinearLayout extends LinearLayout;
SonTextView extends SonTextVieww;
以上是测试基础控件，自己补全即可；
1.测试事件传递顺序（前提：只做视图事件的监听不拦截处理）-不拦截，不处理：
事件类型：0:Down时间，1:抬起事件，2:移动事件；
12-21 12:22:39.172 32056-32056/com.mimhope.baike.touchhope D/MainActivity: MainActivity dispatchTouchEvent = 0    Activity首先接受到按下事件；

12-21 12:22:39.172 32056-32056/com.mimhope.baike.touchhope D/MeLinearLayout: dispatchTouchEvent eventtype = 0 第一层MeLinearLayout接受Activity传递下来事件
12-21 12:22:39.172 32056-32056/com.mimhope.baike.touchhope D/MeLinearLayout: onInterceptEvent eventtype = 0 第一层MeLinearLayout判断是否拦截Activity传递下来事件

12-21 12:22:39.173 32056-32056/com.mimhope.baike.touchhope D/SonLinearLayout: dispatchTouchEvent eventtype = 0 第二层SonLinearLayout接受MeLinearLayout传递下来事件
12-21 12:22:39.173 32056-32056/com.mimhope.baike.touchhope D/SonLinearLayout: onInterceptEvent eventtype = 0 第二层SonLinearLayout判断是否拦截MeLinearLayout传递下来事件

12-21 12:22:39.173 32056-32056/com.mimhope.baike.touchhope D/SonTextView: dispatchTouchEvent eventtype = 0  第三层SonTextView接受SonLinearLayout传递下来事件
12-21 12:22:39.173 32056-32056/com.mimhope.baike.touchhope D/MainActivity: SonTextView OnTouchListener eventtype = 0
onTouchEvent返回false不处理Down事件；
12-21 12:22:39.173 32056-32056/com.mimhope.baike.touchhope D/SonTextView: onTouchEvent eventtype = 0 第三层SonTextView处理SonLinearLayout传递下来事件

12-21 12:22:39.173 32056-32056/com.mimhope.baike.touchhope D/MainActivity: SonLinearLayout OnTouchListener eventtype = 0 第三层不处理按下事件，第二层SonLinearLayout处理；
12-21 12:22:39.173 32056-32056/com.mimhope.baike.touchhope D/SonLinearLayout: onTouchEvent eventtype = 0

12-21 12:22:39.173 32056-32056/com.mimhope.baike.touchhope D/MainActivity: MeLinearLayout OnTouchListener eventtype = 0 第二层不处理按下事件，第一层MeLinearLayout处理；
12-21 12:22:39.173 32056-32056/com.mimhope.baike.touchhope D/MeLinearLayout: onTouchEvent eventtype = 0

12-21 12:22:39.173 32056-32056/com.mimhope.baike.touchhope D/MainActivity: MainActivity onTouchEvent0  第一层MeLinearLayout不处理，MainActivity处理；
12-21 12:26:46.775 32056-32056/com.mimhope.baike.touchhope D/MainActivity: MainActivity dispatchTouchEvent = 2 当确认MainActivity视图不处理，UP，MOVE将会一直传递给MainActivity处理；
12-21 12:26:46.776 32056-32056/com.mimhope.baike.touchhope D/MainActivity: MainActivity onTouchEvent2
12-21 12:22:39.177 32056-32056/com.mimhope.baike.touchhope D/MainActivity: MainActivity dispatchTouchEvent = 1
12-21 12:22:39.177 32056-32056/com.mimhope.baike.touchhope D/MainActivity: MainActivity onTouchEvent1
通过测试日志查看查看：
事件传递可以分为三个阶段 ：
第一阶段Down事件递归方式传递，MainActivity->MeLinearLayout->SonLinearLayout->SonTextView（SonTextView不拦截处理触摸事件）；
第二阶段Down事件冒泡方式调用：SonTextView->SonLinearLayout->MeLinearLayout->MainActivity；
第三阶段MOVE，UP等事件：MainActivity在onTouchEvent()中持续接受移动，抬起事件，确认接受事件的对象MainActivity以后，其他事件MainActivity会持续接受，不再将事件传递给其他视图；
2.测试事件传递顺序（前提：事件监听+事件拦截-在SonLinearLayout的onTouch事件进行处理，return true;）-只处理，不拦截：
12-21 13:05:46.312 354-354/com.mimhope.baike.touchhope D/MainActivity: MainActivity dispatchTouchEvent = 0  Activity首先接受到按下事件；

12-21 13:05:46.312 354-354/com.mimhope.baike.touchhope D/MeLinearLayout: dispatchTouchEvent eventtype = 0 第一层MeLinearLayout接受Activity传递下来事件
12-21 13:05:46.313 354-354/com.mimhope.baike.touchhope D/MeLinearLayout: onInterceptTouchEvent eventtype = 0 第一层MeLinearLayout判断是否拦截Activity传递下来事件

12-21 13:05:46.313 354-354/com.mimhope.baike.touchhope D/SonLinearLayout: dispatchTouchEvent eventtype = 0 第二层SonLinearLayout接受MeLinearLayout传递下来事件
12-21 13:05:46.313 354-354/com.mimhope.baike.touchhope D/SonLinearLayout: onInterceptTouchEvent eventtype = 0 第二层SonLinearLayout判断是否拦截MeLinearLayout传递下来事件

12-21 13:05:46.313 354-354/com.mimhope.baike.touchhope D/SonTextView: dispatchTouchEvent eventtype = 0第三层SonTextView接受SonLinearLayout传递下来事件
12-21 13:05:46.313 354-354/com.mimhope.baike.touchhope D/MainActivity: SonTextView OnTouchListener eventtype = 0
12-21 13:05:46.313 354-354/com.mimhope.baike.touchhope D/SonTextView: onTouchEvent eventtype = 0 第三层不处理按下事件，第二层SonLinearLayout处理；
(在SonLinearLayout的onTouch事件进行处理，return true;)
12-21 13:05:46.313 354-354/com.mimhope.baike.touchhope D/MainActivity: SonLinearLayout OnTouchListener eventtype = 0. 第二层SonLinearLayout处理，则事件不再向上冒泡

12-21 13:05:46.759 354-354/com.mimhope.baike.touchhope D/MainActivity: MainActivity dispatchTouchEvent = 2  MainActivity将接续接受移动，抬起事件，递归传递事件给SonLinearLayout处理；
12-21 13:05:46.759 354-354/com.mimhope.baike.touchhope D/MeLinearLayout: dispatchTouchEvent eventtype = 2
12-21 13:05:46.759 354-354/com.mimhope.baike.touchhope D/MeLinearLayout: onInterceptTouchEvent eventtype = 2
12-21 13:05:46.759 354-354/com.mimhope.baike.touchhope D/SonLinearLayout: dispatchTouchEvent eventtype = 2
12-21 13:05:46.759 354-354/com.mimhope.baike.touchhope D/MainActivity: SonLinearLayout OnTouchListener eventtype = 2

12-21 13:05:47.407 354-354/com.mimhope.baike.touchhope D/MainActivity: MainActivity dispatchTouchEvent = 1
12-21 13:05:47.407 354-354/com.mimhope.baike.touchhope D/MeLinearLayout: dispatchTouchEvent eventtype = 1
12-21 13:05:47.407 354-354/com.mimhope.baike.touchhope D/MeLinearLayout: onInterceptTouchEvent eventtype = 1
12-21 13:05:47.407 354-354/com.mimhope.baike.touchhope D/SonLinearLayout: dispatchTouchEvent eventtype = 1
12-21 13:05:47.407 354-354/com.mimhope.baike.touchhope D/MainActivity: SonLinearLayout OnTouchListener eventtype = 1
通过测试日志查看查看：
事件传递可以分为三个阶段 ：
第一阶段Down事件递归方式传递，MainActivity->MeLinearLayout->SonLinearLayout->SonTextView（SonTextView不处理触摸事件）；
第二阶段Down事件冒泡方式调用：SonTextView->SonLinearLayout；(SonLinearLayout onTouch() return true;)SonLinearLayout返回true说明处理onTouch事件，不再向上冒泡传递；
第三阶段MOVE，UP等事件：SonLinearLayout在onTouchEvent()中持续接受移动，抬起事件，确认接受事件的对象SonLinearLayout以后，其他事件SonLinearLayout会持续接受，不再将事件传递给其他视图；
3.测试事件传递顺序（前提：事件监听+事件拦截-在SonLinearLayout的onInterceptTouchEvent事件进行处理，return true;）：
3.1在SonLinearLayout的onTouch事件进行处理，return false;-只拦截，不处理
12-21 13:32:46.333 1259-1259/com.mimhope.baike.touchhope D/MainActivity: MainActivity dispatchTouchEvent = 0
12-21 13:32:46.333 1259-1259/com.mimhope.baike.touchhope D/MeLinearLayout: dispatchTouchEvent eventtype = 0
12-21 13:32:46.333 1259-1259/com.mimhope.baike.touchhope D/MeLinearLayout: onInterceptTouchEvent eventtype = 0
12-21 13:32:46.333 1259-1259/com.mimhope.baike.touchhope D/SonLinearLayout: dispatchTouchEvent eventtype = 0
12-21 13:32:46.333 1259-1259/com.mimhope.baike.touchhope D/SonLinearLayout: onInterceptTouchEvent eventtype = 0 第二层SonLinearLayout拦截MeLinearLayout传递下来事件，onTouch()处理事件，不再向下派发；

12-21 13:32:46.333 1259-1259/com.mimhope.baike.touchhope D/MainActivity: SonLinearLayout OnTouchListener eventtype = 0 第二层SonLinearLayout的onTouch处理，返回false，则事件再向上冒泡
12-21 13:32:46.333 1259-1259/com.mimhope.baike.touchhope D/SonLinearLayout: onTouchEvent eventtype = 0 第二层只拦截不处理按下事件，第一层MeLinearLayout处理；

12-21 13:32:46.333 1259-1259/com.mimhope.baike.touchhope D/MainActivity: MeLinearLayout OnTouchListener eventtype = 0 第二层不处理按下事件，第一层MeLinearLayout处理
12-21 13:32:46.333 1259-1259/com.mimhope.baike.touchhope D/MeLinearLayout: onTouchEvent eventtype = 0

12-21 13:32:46.333 1259-1259/com.mimhope.baike.touchhope D/MainActivity: MainActivity onTouchEvent0 第一层MeLinearLayout不处理，MainActivity处理；

12-21 13:32:46.454 1259-1259/com.mimhope.baike.touchhope D/MainActivity: MainActivity dispatchTouchEvent = 1  当确认MainActivity视图不处理，UP，MOVE将会一直传递给MainActivity处理；
12-21 13:32:46.454 1259-1259/com.mimhope.baike.touchhope D/MainActivity: MainActivity onTouchEvent1
通过测试日志查看查看：
事件传递可以分为三个阶段 ：
第一阶段Down事件递归方式传递，MainActivity->MeLinearLayout->SonLinearLayout（SonLinearLayout拦截触摸事件）；
第二阶段Down事件冒泡方式调用：SonLinearLayout->MeLinearLayout->MainActivity；
前提：事件监听+事件拦截-在SonLinearLayout的onInterceptTouchEvent事件进行处理，return true;-事件不再向下传递；
在SonLinearLayout的onTouch事件进行处理，return false;-事件继续冒泡继续向上调用；
第三阶段MOVE，UP等事件：MainActivity在onTouchEvent()中持续接受移动，抬起事件，确认接受事件的对象MainActivity以后，其他事件MainActivity会持续接受，不再将事件传递给其他视图；
3.2在SonLinearLayout的onTouch事件进行处理，return true;-拦截+处理
12-21 13:52:52.778 1621-1621/com.mimhope.baike.touchhope D/MainActivity: MainActivity dispatchTouchEvent = 0
12-21 13:52:52.778 1621-1621/com.mimhope.baike.touchhope D/MeLinearLayout: dispatchTouchEvent eventtype = 0
12-21 13:52:52.778 1621-1621/com.mimhope.baike.touchhope D/MeLinearLayout: onInterceptTouchEvent eventtype = 0

12-21 13:52:52.778 1621-1621/com.mimhope.baike.touchhope D/SonLinearLayout: dispatchTouchEvent eventtype = 0
12-21 13:52:52.778 1621-1621/com.mimhope.baike.touchhope D/SonLinearLayout: onInterceptTouchEvent eventtype = 0

12-21 13:52:52.778 1621-1621/com.mimhope.baike.touchhope D/MainActivity: SonLinearLayout OnTouchListener eventtype = 0

12-21 13:52:54.492 1621-1621/com.mimhope.baike.touchhope D/MainActivity: MainActivity dispatchTouchEvent = 1
12-21 13:52:54.492 1621-1621/com.mimhope.baike.touchhope D/MeLinearLayout: dispatchTouchEvent eventtype = 1
12-21 13:52:54.492 1621-1621/com.mimhope.baike.touchhope D/MeLinearLayout: onInterceptTouchEvent eventtype = 1
12-21 13:52:54.492 1621-1621/com.mimhope.baike.touchhope D/SonLinearLayout: dispatchTouchEvent eventtype = 1
12-21 13:52:54.492 1621-1621/com.mimhope.baike.touchhope D/MainActivity: SonLinearLayout OnTouchListener eventtype = 1
通过测试日志查看查看：
事件传递可以分为三个阶段 ：
第一阶段Down事件递归方式传递，MainActivity->MeLinearLayout->SonLinearLayout（SonLinearLayout拦截触摸事件，不再向下传递）；
第二阶段Down事件冒泡方式调用：SonLinearLayout；在SonLinearLayout的onTouch事件进行处理，return true;
前提：事件监听+事件拦截-在SonLinearLayout的onInterceptTouchEvent事件进行处理，return true;-事件不再向下传递；
在SonLinearLayout的onTouch事件进行处理，return true;-事件不再继续冒泡继续向上调用；
第三阶段MOVE，UP等事件：SonLinearLayout在onTouchEvent()中持续接受移动，抬起事件，确认接受事件的对象SonLinearLayout以后，其他事件SonLinearLayout会持续接受，不再将事件传递给其他视图；
4.dispatchTouchEvent和onInterceptTouchEvent区别；
dispatchTouchEvent:决定了事件是否继续分发下去和是否响应事件，false：继续分发，true：不继续分发，此次事件到此结束，也不会有任何控件执行onTouchEvent方法。
onInterceptTouchEvent：决定了是否拦截该事件，false：不拦截，true：拦截，此时当前控件执行onTouchEvent方法。
onTouchEvent：决定了是否消费该事件，false：不消费,true：消费。
5.OnTouchListener、OnTouchEvent、OnClickListener事件分发顺序
调用顺序，OnTouchListener.onTouch（）——>onTouchEvent（）——>OnClickListener.onClick（），其中若onTouch返回值为true，则会屏蔽掉onTouchEvent方法和OnClickListener.onClick方法，若onTouchEvent方法可以被调用，则OnClickListener.onClick方法也一定可以被调用。
一系列点击事件，肯定是以down事件开始，以up事件结束，中间若干个move事件。如果一旦某个元素拦截了某个事件，那么同一个事件序列内的所有事件都会直接交给它处理。
首先，考虑OnTouchListener.onTouch返回的是false，此种情况下，首先down事件按照顺序先经过OnTouchListener.onTouch方法，由于返回false不屏蔽onTouchEvent方法，所以又被分发到onTouchEvent方法，由于该方法默认返回true，即消费了down事件，所以此后的所有事件都由该方法处理，并且不再经过OnTouchListener.onTouch。
6.滑动冲突:分为三种
外部滑动方向和内部滑动方向不一致
典型一个左右滑动的Viewpager+上下滑动的Fragment(Viewpager已经处理了滑动冲突)
外部滑动方向和内部滑动方向一致
上述两种情况的嵌套
对于情况一,判断用户是上下滑动还是左右滑动,可以根据角度,距离差,速度差来进行判断
对于情况二,要根据业务情况来处理规则
外部拦截法:父容器覆写onIntercepted方法,根据情况是否拦截消耗事件(通常选用该方法)
内部拦截法:父容器不做处理,由子控件是否拦截和消耗(要配合requestDisallowInterceptTouchEvent()来使用,父容器不能拦截ACTION_DOWN,因为该事件不受requestDisallowInterceptTouchEvent()控制)
7.super.xxx作用
super.dispatchTouchEvent表示继续分发该事件。
如果return super.onInterceptTouchEvent(ev)， 事件拦截分两种情况:
1.如果该View(ViewGroup)存在子View且点击到了该子View, 则不拦截, 继续分发 给子View 处理, 此时相当于return false。 2.如果该View(ViewGroup)没有子View或者有子View但是没有点击中子View(此时ViewGroup 相当于普通View), 则交由该View的onTouchEvent响应，此时相当于return true。 注意：一般的LinearLayout、 RelativeLayout、FrameLayout等ViewGroup默认不拦截， 而 ScrollView、ListView等ViewGroup则可能拦截，得看具体情况。
如果return super.onTouchEvent(ev)，事件处理分为两种情况：
1.如果该View是clickable或者longclickable的,则会返回true, 表示消费 了该事件, 与返回true一样; 2.如果该View不是clickable或者longclickable的,则会返回false, 表示不 消费该事件,将会向上传递,与返回false一样.
8.ACTION_CANCEL
ACTION_CANCEL 的触发条件是事件被上层拦截，当事件被上层 View 拦截的时候，ChildView 是收不到任何事件的，ChildView 收不到任何事件，自然也不会收到 ACTION_CANCEL 了，所以说这个 ACTION_CANCEL 的正确触发条件并不是这样，那么是什么呢？
事实上，只有上层 View 回收事件处理权的时候，ChildView 才会收到一个 ACTION_CANCEL 事件。
这样说可能不太容易理解，咱举个例子?
例如：上层 View 是一个 RecyclerView，它收到了一个 ACTION_DOWN 事件，由于这个可能是点击事件，所以它先传递给对应 ItemView，询问 ItemView 是否需要这个事件，然而接下来又传递过来了一个 ACTION_MOVE 事件，且移动的方向和 RecyclerView 的可滑动方向一致，所以 RecyclerView 判断这个事件是滚动事件，于是要收回事件处理权，这时候对应的 ItemView 会收到一个 ACTION_CANCEL ，并且不会再收到后续事件。
参考：
https://segmentfault.com/a/1190000021534817
https://blog.csdn.net/yh18668197127/article/details/84568175
https://www.gcssloop.com/customview/motionevent