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

Flutter go_router中如何在导航时读取变化前的当前路由?

在GoRouter中获取导航前的路由状态

GoRouter本身没有提供类似auto_router中onNavigation的直接回调,但可以通过两种更简洁的方式实现需求,比手动重写所有NavigationObserver方法更高效:

方法一:自定义路由跟踪器结合refreshListenable

通过ChangeNotifier实现一个路由跟踪器,在导航事件触发时自动记录前后路由:

class RouteTracker extends ChangeNotifier {
  String? previousRoute;
  String? currentRoute;

  void updateRoutes(String newRoute) {
    previousRoute = currentRoute;
    currentRoute = newRoute;
    notifyListeners();
  }
}

将这个跟踪器传入GoRouter的refreshListenable,并在navigatorBuilder中更新路由状态:

final routeTracker = RouteTracker();

final GoRouter router = GoRouter(
  refreshListenable: routeTracker,
  navigatorBuilder: (context, state, child) {
    if (state.location != routeTracker.currentRoute) {
      routeTracker.updateRoutes(state.location);
    }
    return child;
  },
  routes: [
    // 你的路由定义
  ],
);

之后在任意需要的地方监听routeTracker,就能直接获取previousRoute(导航前路由)和currentRoute(新路由)。

方法二:封装简化版NavigationObserver

无需重写所有方法,只针对核心导航事件(push、pop)做处理,利用路由的settings.name获取前后路由信息:

class SimpleRouteObserver extends NavigatorObserver {
  final void Function(String? previousRoute, String currentRoute)? onNavigation;

  SimpleRouteObserver({this.onNavigation});

  @override
  void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
    super.didPush(route, previousRoute);
    _notify(previousRoute?.settings.name, route.settings.name);
  }

  @override
  void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
    super.didPop(route, previousRoute);
    _notify(route.settings.name, previousRoute?.settings.name);
  }

  void _notify(String? prev, String? curr) {
    if (onNavigation != null && curr != null) {
      onNavigation!(prev, curr);
    }
  }
}

在GoRouter中添加这个观察者:

final GoRouter router = GoRouter(
  observers: [
    SimpleRouteObserver(
      onNavigation: (previousRoute, currentRoute) {
        // 在这里处理路由变化逻辑
        print('从 $previousRoute 导航到 $currentRoute');
      },
    ),
  ],
  routes: [
    // 你的路由定义
  ],
);

如果需要处理replace、remove等其他导航事件,可按需重写对应的方法即可,比全量重写更轻量化。

补充说明

  • GoRouter的redirect回调只能获取新路由的GoRouterState,无法直接拿到导航前的路由信息,因此不适合用于前后路由对比场景。
  • 两种方法各有侧重:方法一更适合需要全局联动UI更新的场景,方法二更适合仅需监听导航事件做逻辑处理的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 03:32:37