Skip to content
阅读进度

开发一个可滑动的自定义 ViewGroup 时,如何处理子 View 的触摸事件分发? ​

返回 View 与显示链路 目录

标准回答 ​

父 ViewGroup 通过 dispatchTouchEvent 分发,在 onInterceptTouchEvent 判断是否接管;不拦截则交子 View,拦截后由父 onTouchEvent 处理。父容器中途拦截时,原子目标会收到 ACTION_CANCEL。

**实现滑动的关键:**DOWN 记录位置,MOVE 超过 touchSlop 且符合方向后再拦截;UP/CANCEL 清状态。处理好子 View 的 requestDisallowInterceptTouchEvent;需要协作滚动时采用嵌套滚动协议。

通俗例子 ​

横向轮播里有可点击卡片:轻点交给卡片,明显横拖后由轮播容器接管,卡片通常收到 ACTION_CANCEL。

深入解释 ​

**事件怎么走:**父容器先有机会通过 onInterceptTouchEvent 判断是否接管。若不接管,事件继续交给命中的子 View;子项是否消费还影响后续分发。

**接管以后怎么办:**父容器在滑动过程中开始拦截时,原先处理手势的子项通常收到 ACTION_CANCEL。父子双方都要清理按压和拖动状态,避免出现按钮一直按下的效果。

易混淆点 ​

不要从 ACTION_DOWN 起无条件抢走事件,也要处理 CANCEL 和多指状态。

内容来源 ​

用完整回答理解机制,用真实证据解释项目。