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

Android:如何移除ViewTreeObserver的GlobalLayoutListener?当前方法是否正确?

正确移除ViewTreeObserver监听器的方法

你当前的代码存在核心错误:你添加的是OnGlobalLayoutListener布局变化监听器,但移除时调用了针对OnGlobalFocusChangeListener焦点变化监听器的方法,两者完全不匹配,根本无法移除你之前添加的监听器。

正确步骤:

  1. 保存监听器实例引用
    不能直接用匿名lambda添加监听器,因为移除时需要传入同一个实例才能生效,所以要把监听器存为Fragment的成员变量。

  2. 调用对应类型的移除方法
    监听器类型和移除方法是一一对应的:

    • 添加OnGlobalLayoutListener → 用removeOnGlobalLayoutListener移除
    • 添加OnGlobalFocusChangeListener → 用removeOnGlobalFocusChangeListener移除
    • 其他监听器类型同理,调用同名的remove方法
  3. 选择合适的移除时机
    对于Fragment,推荐在onDestroyView中移除监听器,因为此时视图即将被销毁,能更及时避免内存泄漏,比onDestroy更合适。

修改后的代码示例:

class MyFragment: Fragment() {
    // 保存布局变化监听器的实例引用
    private val globalLayoutListener = ViewTreeObserver.OnGlobalLayoutListener {
        doSomething()
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    
        binding.root.viewTreeObserver.addOnGlobalLayoutListener(globalLayoutListener)
    }
    
    override fun onDestroyView() {
        super.onDestroyView()
        // 调用对应类型的移除方法,传入同一个监听器实例
        binding.root.viewTreeObserver.removeOnGlobalLayoutListener(globalLayoutListener)
    }
}

额外说明

如果你的minSdkVersion >= 16,也可以使用removeOnGlobalLayoutListener的重载方法,但保持监听器实例一致是最通用、不易出错的做法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 10:53:10