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

如何通过非底部导航栏按钮切换go_router底部导航栏状态

解决GoRouter中跨分支跳转时底部导航不切换的问题

要实现从Section A页面跳转到Section B详情页时同步切换底部导航状态,你需要使用StatefulNavigationShell的goBranch方法,而非直接调用context.push。该方法会同时切换底部导航的选中分支,并导航到目标页面。

具体修改步骤

  1. 在HomePage中获取当前的StatefulNavigationShell实例
  2. 调用goBranch方法,传入目标分支的索引(Section B对应索引1),并指定initialLocation为目标详情页路径/b/detail

修改HomePage中的按钮代码:

ElevatedButton(
  onPressed: () {
    final shell = StatefulNavigationShell.of(context);
    shell.goBranch(
      1,
      initialLocation: '/b/detail',
    );
  },
  child: const Text("Move to B Detail Page"),
),

同理,若需从Section B页面跳转到Section A详情页,可使用同样逻辑:

ElevatedButton(
  onPressed: () {
    final shell = StatefulNavigationShell.of(context);
    shell.goBranch(
      0,
      initialLocation: '/a/detail',
    );
  },
  child: const Text("Move to A Detail Page"),
),

原方法无效原因

直接调用context.push("/b/detail")仅会在当前导航栈中添加新页面,不会触发StatefulShellRoute的分支切换逻辑,底部导航的currentIndex仍保持原分支索引。而goBranch方法会主动切换分支,并将指定路径作为该分支的初始导航位置,从而同步更新底部导航的选中状态。

修改后的完整代码

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

void main() {
  runApp(MaterialApp.router(
    routerConfig: router,
  ));
}

final GlobalKey<NavigatorState> _rootNavigatorKey = GlobalKey<NavigatorState>(debugLabel: 'root');
final GlobalKey<NavigatorState> _homeNavigatorKey = GlobalKey<NavigatorState>(debugLabel: 'a');
final GlobalKey<NavigatorState> _settingsNavigatorKey = GlobalKey<NavigatorState>(debugLabel: 'b');

final GoRouter router = GoRouter(
    navigatorKey: _rootNavigatorKey,
    initialLocation: '/a',
    routes: <RouteBase> [
      StatefulShellRoute.indexedStack(
        builder: (context, state, navigationShell){
          return ScaffoldWithNavBar(navigationShell: navigationShell,);
        },
        branches: <StatefulShellBranch>[
          StatefulShellBranch(
            navigatorKey: _homeNavigatorKey,
            routes: <RouteBase>[
              GoRoute(
                path: '/a',
                builder: (context, state) => const HomePage(pageTitle: "A",),
                routes: [
                  GoRoute(
                    path: 'detail',
                    builder: (context, state) => const DetailPage(pageTitle: "A",),
                  ),
                ],
              ),
            ],
          ),
          StatefulShellBranch(
            navigatorKey: _settingsNavigatorKey,
            routes: [
              GoRoute(
                path: '/b',
                builder: (context, state) => const HomePage(pageTitle: "B",),
                routes: [
                  GoRoute(
                    path: 'detail',
                    builder: (context, state) => const DetailPage(pageTitle: "B",),
                  ),
                ],
              ),
            ],
          ),
        ],
      ),
    ]
);

class ScaffoldWithNavBar extends StatelessWidget {
  const ScaffoldWithNavBar({
    required this.navigationShell,
    Key? key,
  }) : super(key: key ?? const ValueKey<String>('ScaffoldWithNavBar'));

  final StatefulNavigationShell navigationShell;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: navigationShell,
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Section A'),
          BottomNavigationBarItem(icon: Icon(Icons.work), label: 'Section B'),
        ],
        currentIndex: navigationShell.currentIndex,
        onTap: (int index) => navigationShell.goBranch(index),
      ),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({
    super.key,
    required this.pageTitle,
  });
  final String pageTitle;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text("$pageTitle Home Page"),
      ),
      body: Center(
        child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              ElevatedButton(
                onPressed: () {
                  final shell = StatefulNavigationShell.of(context);
                  shell.goBranch(
                    0,
                    initialLocation: '/a/detail',
                  );
                },
                child: const Text("Move to A Detail Page"),
              ),
              ElevatedButton(
                onPressed: () {
                  final shell = StatefulNavigationShell.of(context);
                  shell.goBranch(
                    1,
                    initialLocation: '/b/detail',
                  );
                },
                child: const Text("Move to B Detail Page"),
              ),
            ]
        ),
      ),
    );
  }
}

class DetailPage extends StatelessWidget {
  const DetailPage({
    super.key,
    required this.pageTitle,
  });
  final String pageTitle;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text("$pageTitle Detail Page"),
      ),
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 03:53:10