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
相关产品推荐
相关产品推荐

