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

如何在Go Router中根据栈状态选择性Push或Pop路由?

实现根据回退栈状态自动选择Pop或Push的功能

核心思路是判断当前导航栈中目标页面(Home)是否是当前页面的直接前一个路由,以此决定执行Pop还是Push操作。下面提供两种实用实现方式:

方式一:直接在按钮点击事件中判断(基础版)

假设你使用命名路由管理页面(推荐),给每个页面路由设置唯一名称(比如/home、/profile、/info),代码如下:

ElevatedButton(
  onPressed: () {
    final navigator = Navigator.of(context);
    // 获取当前导航栈的路由名称列表
    final routeNames = navigator.routeInformationProvider?.value.routeNames ?? [];
    
    // 检查前一个路由是否是Home页面
    if (routeNames.length >= 2 && routeNames[routeNames.length - 2] == '/home') {
      // 前一个页面是Home,执行Pop回到Home
      navigator.pop();
    } else {
      // 前一个页面不是Home,Push新的Home页面
      navigator.pushNamed('/home');
    }
  },
  child: const Text('返回首页'),
)

方式二:扩展NavigatorState实现自定义方法(优雅版)

如果你希望像context.popOrPush(route)一样调用,可以给NavigatorState写一个扩展类,封装判断逻辑:

// 定义扩展类
extension NavigatorPopOrPushExtension on NavigatorState {
  void popOrPush(String targetRouteName) {
    final routeNames = routeInformationProvider?.value.routeNames ?? [];
    // 判断当前页面的直接前一个路由是否是目标路由
    if (routeNames.length >= 2 && routeNames[routeNames.length - 2] == targetRouteName) {
      pop();
    } else {
      pushNamed(targetRouteName);
    }
  }
}

使用时只需一行代码:

ElevatedButton(
  onPressed: () {
    Navigator.of(context).popOrPush('/home');
  },
  child: const Text('返回首页'),
)

适配非命名路由场景

如果没用命名路由,可以通过路由的settings传递标识,或者直接判断页面类型:

extension NavigatorPopOrPushExtension on NavigatorState {
  void popOrPushToHome() {
    Route? previousRoute;
    var currentRoute = route;
    // 遍历路由栈,查找前一个页面是否是HomeScreen
    while (currentRoute != null) {
      final parentRoute = currentRoute.parent;
      if (parentRoute != null && parentRoute is MaterialPageRoute) {
        final pageWidget = parentRoute.builder(context);
        if (pageWidget.runtimeType == HomeScreen) {
          previousRoute = parentRoute;
          break;
        }
      }
      currentRoute = parentRoute;
    }
    // 如果前一个页面是Home,执行Pop;否则Push新Home
    if (previousRoute != null && route.parent == previousRoute) {
      pop();
    } else {
      push(MaterialPageRoute(builder: (context) => const HomeScreen()));
    }
  }
}

调用方式:

Navigator.of(context).popOrPushToHome();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 12:53:18