如何在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
相关产品推荐
相关产品推荐

