You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何子View可调用getParent().requestDisallowInterceptTouchEvent(true)?父拦截时如何执行?

子View调用requestDisallowInterceptTouchEvent的执行逻辑解析

示例代码

@Override 
public boolean dispatchTouchEvent(MotionEvent ev) { 
    // why this code can be executed. 
    getParent().requestDisallowInterceptTouchEvent(true); 
    return super.dispatchTouchEvent(ev); 
} 

问题

getParent().requestDisallowInterceptTouchEvent(true)用于告知父View不要拦截触摸事件,但如果父View已经拦截了触摸事件,事件无法传递到子View,那么子View是如何执行该方法的?


这问题问到点子上了,咱们得从Android触摸事件的传递流程来拆解:

首先要明确一个核心规则:触摸事件的分发是从上到下,拦截是有阶段的。

  • 当第一个触摸事件(ACTION_DOWN)到来时,系统会从Activity的Window开始,把事件层层往下传递给子View。这个过程中,父View的onInterceptTouchEvent会被触发,如果它返回false(不拦截),事件就会落到子View的dispatchTouchEvent方法里——这时候你的这段代码就会执行,提前告诉父View:“后面的触摸事件(比如ACTION_MOVE、ACTION_UP)别拦我,我自己处理”。
  • 那如果父View在ACTION_DOWN阶段就返回true拦截了呢?那确实,子View的dispatchTouchEvent根本不会被调用,这段代码自然也跑不起来。但实际开发中,咱们用这个方法的场景,大多是父View不会在ACTION_DOWN时拦截,而是在后续的滑动事件中才可能抢事件——这时候子View已经在ACTION_DOWN阶段完成了“禁止拦截”的请求,父View就会遵守这个约定,不再拦截后续事件。

举个常见的场景:比如ScrollView嵌套RecyclerView时,RecyclerView会在ACTION_DOWN触发时调用这个方法,提前给ScrollView打“招呼”,这样用户在RecyclerView上滑动时,ScrollView就不会把事件抢过去自己滚动了。

最后再总结下:

  • 只有父View没有拦截ACTION_DOWN事件时,子View才有机会拿到事件并执行这段代码;
  • 如果父View一开始就拦截了ACTION_DOWN,子View根本没机会执行这个方法,这种情况下这个调用也就不存在了。

内容的提问来源于stack exchange,提问作者Guo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:02:11