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

为StatefulShellRoute添加AnimatedSwitcher转场时出现重复GlobalKey错误

问题原因

StatefulNavigationShell内部自带全局唯一的GlobalKey,你直接用AnimatedSwitcher包裹它时,动画切换期间新旧两个SizedBox会同时持有同一个navigationShell实例,导致全局键重复冲突——Flutter不允许同一个全局键的widget同时存在于widget树的两个位置。

解决方案

放弃直接包裹navigationShell,改为让AnimatedSwitcher切换当前分支的页面实例,而非整个navigationShell。具体代码修改如下:

return StatefulShellRoute(
  builder: (context, state, navigationShell) {
    return Scaffold(
      body: AnimatedSwitcher(
        duration: const Duration(milliseconds: 500),
        switchInCurve: Curves.ease,
        switchOutCurve: Curves.ease,
        // 用当前索引作为唯一Key,确保AnimatedSwitcher识别页面变化
        child: KeyedSubtree(
          key: ValueKey(navigationShell.currentIndex),
          child: navigationShell.currentBranch,
        ),
      ),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: navigationShell.currentIndex,
        onTap: (index) {
          navigationShell.goBranch(
            index,
            // 仅首次进入分支时跳转到初始路由,避免重复重建
            initialLocation: index != navigationShell.currentIndex,
          );
        },
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: "首页"),
          BottomNavigationBarItem(icon: Icon(Icons.settings), label: "设置"),
        ],
      ),
    );
  },
  branches: [
    StatefulShellBranch(
      routes: [
        GoRoute(
          path: "/",
          builder: (context, state) => const HomePage(),
        ),
      ],
    ),
    StatefulShellBranch(
      routes: [
        GoRoute(
          path: "/settings",
          builder: (context, state) => const SettingsPage(),
        ),
      ],
    ),
  ],
);
说明
  • 这种方式保留了StatefulShellRoute的状态管理能力(各分支页面状态会被缓存),同时实现了切换转场动画。
  • 通过ValueKey(navigationShell.currentIndex)确保AnimatedSwitcher能正确识别页面切换,避免全局键冲突——因为每次切换时处理的是不同分支的页面实例,而非同一个navigationShell。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 19:27:30