Flutter中如何获取导航栈内所有已push的路由?
Flutter获取导航栈所有路由及路由名称的方案
Flutter官方没有公开直接读取导航栈的API,但可以通过以下两种常用方式实现需求:
方案一:自定义NavigatorObserver全局维护路由栈(生产环境推荐)
这个方案兼容性最强,不会依赖SDK内部私有实现,步骤如下:
- 自定义路由观察者类,继承
NavigatorObserver,内部维护路由栈列表:
class CustomNavigatorObserver extends NavigatorObserver { // 内部维护路由栈 static final List<Route<dynamic>> _routeStack = []; /// 获取所有路由实例的不可变列表 List<Route<dynamic>> get allRoutes => List.unmodifiable(_routeStack); /// 获取所有路由的名称列表,未设置name的路由对应值为null List<String?> get allRouteNames => _routeStack.map((route) => route.settings.name).toList(); @override void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) { _routeStack.add(route); super.didPush(route, previousRoute); } @override void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) { _routeStack.remove(route); super.didPop(route, previousRoute); } @override void didReplace({Route<dynamic>? newRoute, Route<dynamic>? oldRoute}) { if (oldRoute != null && newRoute != null) { final targetIndex = _routeStack.indexOf(oldRoute); if (targetIndex != -1) _routeStack[targetIndex] = newRoute; } super.didReplace(newRoute: newRoute, oldRoute: oldRoute); } @override void didRemove(Route<dynamic> route, Route<dynamic>? previousRoute) { _routeStack.remove(route); super.didRemove(route, previousRoute); } }
- 将自定义观察者注册到根应用的
navigatorObservers属性中:
final CustomNavigatorObserver navigatorObserver = CustomNavigatorObserver(); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( navigatorObservers: [navigatorObserver], // 其余应用配置 ); } }
- 任意位置需要获取路由栈时,直接调用对应的getter即可:
// 获取所有路由实例 List<Route> routes = navigatorObserver.allRoutes; // 获取所有路由名称 List<String?> routeNames = navigatorObserver.allRouteNames;
方案二:读取Navigator私有属性(仅适合调试场景)
如果只是开发调试阶段临时查看路由栈,可以通过反射直接读取NavigatorState的内部私有属性,该方案依赖SDK内部实现,不同Flutter版本属性名可能有变更,不建议上生产环境:
import 'dart:mirrors'; List<Route> getDebugNavigatorStack(BuildContext context) { final NavigatorState navigator = Navigator.of(context); final InstanceMirror navigatorMirror = reflect(navigator); // 部分Flutter版本私有属性名可能为_history/_transitions,可自行调试适配 final List history = navigatorMirror.getField(const Symbol('_history')).reflectee; return history.map((entry) => entry.route as Route).toList(); }
第三方路由框架适配
- 如果使用GoRouter:可直接调用
GoRouter.of(context).routerDelegate.currentConfiguration.matches获取路由栈信息,每个匹配项的matchedLocation就是路由路径 - 如果使用Fluro等其他路由框架:也可以参照方案一的思路,给框架注册自定义路由观察者维护栈列表即可
注意事项
- 路由名称依赖你push路由时给
RouteSettings的name字段赋值,未主动赋值的路由获取到的名称会是null - Dialog、BottomSheet这类弹窗路由默认也会被计入栈中,如果不需要可以在获取后过滤掉对应
Route类型即可
内容的提问来源于stack exchange,提问作者Omar Abdelazeem
相关产品推荐
相关产品推荐

