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

使用ShellRoute时context.push无法跳转子路由的问题求助

问题描述

我正在使用Flutter开发一款睡眠分析应用,刚采用go_router管理路由。主界面是带有嵌套导航栏的4个页面,部分路由包含子路由,比如属于ShellRoute的/settings路由下有/settings/profile、/settings/password等子路由。但我无法通过context.push('/settings/my_subroute')实现跳转,context.go则可以正常工作。我需要通过push实现带返回按钮的页面跳转,以下是我的router.dart代码:

final GoRouter router = GoRouter(
  initialLocation: '/auth',
  routes: [
    ShellRoute(
      builder: (context, state, child) {
        return const BottomNavBar();
      },
      routes: <RouteBase>[
        GoRoute(
          name: 'home',
          path: '/',
          builder: (context, state) => const HomeScreen(),
        ),
        GoRoute(
          name: 'sleep',
          path: '/sleep',
          builder: (context, state) => const SleepScreen(),
        ),
        GoRoute(
          name: 'dreams',
          path: '/dreams',
          builder: (context, state) => const DreamsScreen(),
          routes: <RouteBase>[
            GoRoute(
              path: 'add',
              builder: (context, state) => const AddDreamScreen(),
            ),
          ],
        ),
        GoRoute(
          name: 'settings',
          path: '/settings',
          builder: (context, state) => const SettingsMainScreen(),
          routes: <RouteBase>[
            GoRoute(
              name: 'profile',
              path: 'profile',
              builder: (context, state) => const SettingsProfileScreen(),
            ),
            GoRoute(
              name: 'email',
              path: 'email',
              builder: (context, state) => const SettingsEmailScreen(),
            ),
            GoRoute(
              name: 'password',
              path: 'password',
              builder: (context, state) => const SettingsPasswordScreen(),
            ),
          ],
        ),
      ],
    ),
  ],
);

我怀疑是ShellRoute导致的上下文问题,也不确定是否支持该用法,请问如何让context.push生效?


解决方案

1. 修复ShellRoute的上下文传递(核心问题)

你的ShellRoute构建时没有将child参数传递给BottomNavBar,导致子路由的导航上下文无法正确关联到ShellRoute的嵌套栈中。这是push失效的主要原因。

修改ShellRoute的builder:

ShellRoute(
  builder: (context, state, child) {
    return BottomNavBar(child: child); // 移除const,传入child参数
  },
  // 其余路由配置不变
)

同步修改BottomNavBar的定义,接收并显示传入的child:

class BottomNavBar extends StatelessWidget {
  final Widget child;
  const BottomNavBar({super.key, required this.child});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: child, // 用这个child显示当前路由的页面内容
      bottomNavigationBar: BottomNavigationBar(
        // 你的导航栏项和切换逻辑
      ),
    );
  }
}

2. 使用正确的跳转方式

修复上下文后,选择以下两种方式实现push跳转:

  • 相对路径跳转:在SettingsMainScreen内直接使用相对路径:
    context.push('profile'); // 等价于 /settings/profile
    
  • 命名路由跳转:利用路由的name属性,避免路径拼写错误:
    context.pushNamed('profile');
    

3. 区分push和go的使用场景

  • push:用于在当前页面栈顶部添加新页面(比如从设置主页面进入个人资料页,需要返回按钮)
  • go:用于替换整个页面栈(比如底部导航栏切换页面,不需要返回上一个导航项页面)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 14:05:24