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

Flutter Stateful Shell Route问题:返回按钮无法正常回退

问题解决:Flutter底部导航切换后返回键直接退出应用

问题原因

使用GoRouter的StatefulShellRoute实现底部导航时,每个分支对应独立的导航栈。默认返回键仅处理当前分支的栈,当当前分支栈只有初始页面时,会直接触发应用退出,而非切换到之前选中的分支页面。

解决方案

在HomePage中通过WillPopScope拦截返回事件,优先尝试回退当前分支的导航栈;若当前分支无法回退,则切换回初始分支(如/feed);只有当前在初始分支且无法回退时,才允许退出应用。

修改后的home_page.dart代码

class HomePage extends StatefulWidget {
  const HomePage(this.child, {super.key});

  final StatefulNavigationShell child;

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        // 先尝试回退当前分支的导航栈
        final canPopCurrentBranch = await widget.child.currentBranchNavigator?.canPop() ?? false;
        if (canPopCurrentBranch) {
          widget.child.currentBranchNavigator?.pop();
          return false;
        }

        // 如果当前分支无法回退,且不是初始分支(这里初始分支是index 0,对应/feed)
        if (widget.child.currentIndex != 0) {
          widget.child.goBranch(0);
          return false;
        }

        // 当前是初始分支且无法回退,允许退出应用
        return true;
      },
      child: Scaffold(
        appBar: AppBar(
            title: const Row(children: [
          Icon(Icons.movie),
          SizedBox(
            width: 8,
          ),
          Text('Comics')
        ])),
        body: widget.child,
        bottomNavigationBar: NavigationBar(
            onDestinationSelected: (int index) {
              widget.child.goBranch(index);
            },
            selectedIndex: widget.child.currentIndex,
            destinations: const [
              NavigationDestination(icon: Icon(Icons.fiber_new), label: 'Feed'),
              NavigationDestination(icon: Icon(Icons.book), label: 'Library'),
              NavigationDestination(icon: Icon(Icons.search), label: 'Discover'),
            ]),
      ),
    );
  }
}

补充说明

  • widget.child.currentBranchNavigator可获取当前分支的导航器,通过canPop()判断是否有页面可以回退。
  • 初始分支的index根据你的配置设置(这里是0,对应/feed),如果你的初始分支是其他,修改对应的index即可。
  • 处理后返回键逻辑:先回退当前分支内的页面,无页面可回退时切换回初始分支,仅在初始分支且无页面可回退时退出应用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 18:27:35