From 54d13c17d608d1e15f5c32a4036caf44a156be96 Mon Sep 17 00:00:00 2001 From: Omooo <869759698@qq.com> Date: Wed, 12 Aug 2020 17:39:07 +0800 Subject: [PATCH] =?UTF-8?q?Update=20View=20=E4=BD=93=E7=B3=BB=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E5=8F=A3=E6=B0=B4=E8=AF=9D.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- blogs/Android/口水话/View 体系相关口水话.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blogs/Android/口水话/View 体系相关口水话.md b/blogs/Android/口水话/View 体系相关口水话.md index b510be9..bc4f7fd 100644 --- a/blogs/Android/口水话/View 体系相关口水话.md +++ b/blogs/Android/口水话/View 体系相关口水话.md @@ -39,7 +39,7 @@ WMS 是所有 Window 窗口的管理者,它负责 Window 的添加和删除、 DecorView -> Activity -> PhoneWindow -> DecorView -> ViewGroup -> View ``` -这里面涉及了三个元素,Activity、ViewGroup 和 View。Activity 的 dispatchTouchEvent 前面说过,它的 onTouchEvent 一般都是返回 false 不消费往下传;在说 View 的 dispatchTouchEvent,如果注册了 OnTouchListener 就调用其 onTouch 方法,如果 onTouch 返回 false 还会接着调用 onTouchEvent 函数,onTouchEvent 作为一种兜底方案,它在内部会根据 MotionEvent 的不同类型做相应处理,比如是 ACTION_UP 就需要执行 performClick 函数。ViewGroup 因为涉及对子 View 的处理,其派发流程没有 View 那么简单直接,它重写了 dispatchTouchEvent 方法,如果 ViewGroup 允许拦截,就调用其 onInterceptTouchEvent 来判断是否要真正执行拦截了,如果拦截了就交由自己的 onTouchEvent 处理,如果不拦截,就从后遍历子 View 处理,它有两个函数可以过滤子 View,一个是判断这个子 View 是否接受 Pointer Events 事件,另一个是判断落点有没有落在子 View 范围内。如果都满足,则调用其 dispatchTouchEvent 处理。如果该子 View 是一个 ViewGroup 就继续调用其 dispatchTouchEvent,否则就是 View 的 dispatchTouchEvent 方法,如此循环往复,直到事件真正被处理。 +这里面涉及了三个元素,Activity、ViewGroup 和 View。Activity 的 dispatchTouchEvent 前面说过,它的 dispatchTouchEvent 一般都是返回 false 不消费往下传;在说 View 的 dispatchTouchEvent,如果注册了 OnTouchListener 就调用其 onTouch 方法,如果 onTouch 返回 false 还会接着调用 onTouchEvent 函数,onTouchEvent 作为一种兜底方案,它在内部会根据 MotionEvent 的不同类型做相应处理,比如是 ACTION_UP 就需要执行 performClick 函数。ViewGroup 因为涉及对子 View 的处理,其派发流程没有 View 那么简单直接,它重写了 dispatchTouchEvent 方法,如果 ViewGroup 允许拦截,就调用其 onInterceptTouchEvent 来判断是否要真正执行拦截了,如果拦截了就交由自己的 onTouchEvent 处理,如果不拦截,就从后遍历子 View 处理,它有两个函数可以过滤子 View,一个是判断这个子 View 是否接受 Pointer Events 事件,另一个是判断落点有没有落在子 View 范围内。如果都满足,则调用其 dispatchTouchEvent 处理。如果该子 View 是一个 ViewGroup 就继续调用其 dispatchTouchEvent,否则就是 View 的 dispatchTouchEvent 方法,如此循环往复,直到事件真正被处理。 伪代码表示为: @@ -91,7 +91,7 @@ Vsync 信号可以理解为底层硬件的一个消息脉冲,它每 16ms 发 在项目中,我们遇到了一个 ViewPager2 嵌套 RecyclerView 滑动过于灵敏的问题,即稍微滑动一点 RecyclerView 就会导致 ViewPager2 切换,这在使用 ViewPager 是没啥问题,但是 ViewPager2 内部使用的也是 RecyclerView + SnapHelper 做横向滑动,导致了滑动灵敏问题。又因为 ViewPager2 是 final 的,所以只能使用内部拦截法。 -解决办法是:重写 ViewPager2 的根布局 FrameLayout 的 dispatchTouchEvent,判断如果 dx>dy+30,即表明是横向滑动,requestDisallowTouchEvent(false) 允许 ViewPager2 去拦截处理。详细代码如下: +解决办法是:重写 ViewPager2 的根布局 FrameLayout 的 dispatchTouchEvent,判断如果 dx>dy+30,即表明是横向滑动,requestDisallowInterceptTouchEvent(false) 允许 ViewPager2 去拦截处理。详细代码如下: ```java int dx = 0;