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

如何在Navigator 2.0中订阅Route变更事件

Flutter 深层组件监听路由变更的实现方法

方案1:自定义NavigatorObserver全局监听(通用方案)

这是官方推荐的标准实现方式,无需修改现有路由逻辑,全局注册一次即可全链路监听路由变更:

  • 第一步:自定义继承自NavigatorObserver的单例类,内部封装路由变更事件的广播逻辑
import 'package:flutter/material.dart';
import 'dart:async';

class AppRouteObserver extends NavigatorObserver {
  // 单例实例
  static final AppRouteObserver instance = AppRouteObserver._internal();
  AppRouteObserver._internal();

  // 路由变更广播流
  final StreamController<Route?> _routeChangeController = StreamController<Route?>.broadcast();
  Stream<Route?> get routeChangeStream => _routeChangeController.stream;

  @override
  void didPush(Route route, Route? previousRoute) {
    _routeChangeController.add(route);
    super.didPush(route, previousRoute);
  }

  @override
  void didPop(Route route, Route? previousRoute) {
    _routeChangeController.add(previousRoute);
    super.didPop(route, previousRoute);
  }

  @override
  void didReplace({Route? newRoute, Route? oldRoute}) {
    _routeChangeController.add(newRoute);
    super.didReplace(newRoute: newRoute, oldRoute: oldRoute);
  }

  @override
  void didRemove(Route route, Route? previousRoute) {
    _routeChangeController.add(previousRoute);
    super.didRemove(route, previousRoute);
  }

  // 全局销毁时调用,避免内存泄漏
  void dispose() {
    _routeChangeController.close();
  }
}
  • 第二步:将自定义观察者注册到MaterialApp的Navigator配置中
MaterialApp(
  navigatorObservers: [AppRouteObserver.instance],
  // 其余原有配置保持不变
)
  • 第三步:在需要监听路由的深层组件中订阅流事件
class DeepNestedWidget extends StatefulWidget {
  const DeepNestedWidget({super.key});

  @override
  State<DeepNestedWidget> createState() => _DeepNestedWidgetState();
}

class _DeepNestedWidgetState extends State<DeepNestedWidget> {
  late StreamSubscription _routeSub;

  @override
  void initState() {
    super.initState();
    _routeSub = AppRouteObserver.instance.routeChangeStream.listen((currentRoute) {
      // 示例:获取当前路由名做逻辑判断
      final routeName = currentRoute?.settings.name;
      if(routeName == '/target_page') {
        // 执行你需要的业务逻辑
      }
    });
  }

  @override
  void dispose() {
    // 必须取消订阅避免内存泄漏
    _routeSub.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // 原有组件逻辑
    return const SizedBox.shrink();
  }
}

方案2:当前路由状态监听(仅适用于监听组件所在路由的状态变化)

如果只需要感知当前组件所属路由的激活/失活、参数变化等状态,无需跨路由监听,可以直接用ModalRoute的监听能力:

@override
void initState() {
  super.initState();
  // 获取当前组件对应的Route对象
  final currentRoute = ModalRoute.of(context);
  currentRoute?.addListener(() {
    // 路由状态变更时触发
    final isCurrent = currentRoute.isCurrent;
    final routeArgs = currentRoute.settings.arguments;
    // 处理业务逻辑
  });
}

注意事项

  • 如果使用GoRouter、GetX等第三方路由框架,框架本身已封装路由监听能力,直接调用框架提供的API即可,无需重复封装NavigatorObserver
  • 所有流订阅、事件监听必须在组件dispose生命周期中注销,避免内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 03:39:02