外观
开发一个可滑动的自定义 ViewGroup 时,如何处理子 View 的触摸事件分发?
标准回答
父 ViewGroup 通过 dispatchTouchEvent 分发,在 onInterceptTouchEvent 判断是否接管;不拦截则交子 View,拦截后由父 onTouchEvent 处理。父容器中途拦截时,原子目标会收到 ACTION_CANCEL。
**实现滑动的关键:**DOWN 记录位置,MOVE 超过 touchSlop 且符合方向后再拦截;UP/CANCEL 清状态。处理好子 View 的 requestDisallowInterceptTouchEvent;需要协作滚动时采用嵌套滚动协议。
通俗例子
横向轮播里有可点击卡片:轻点交给卡片,明显横拖后由轮播容器接管,卡片通常收到 ACTION_CANCEL。
深入解释
**事件怎么走:**父容器先有机会通过 onInterceptTouchEvent 判断是否接管。若不接管,事件继续交给命中的子 View;子项是否消费还影响后续分发。
**接管以后怎么办:**父容器在滑动过程中开始拦截时,原先处理手势的子项通常收到 ACTION_CANCEL。父子双方都要清理按压和拖动状态,避免出现按钮一直按下的效果。
易混淆点
不要从 ACTION_DOWN 起无条件抢走事件,也要处理 CANCEL 和多指状态。
内容来源
- Android · AI Agent 知识手册 · 原条目
2.4.1