如何在Flutter中通过GetX实现同款嵌套导航功能?
问题描述

图中展示了一种导航效果:每个标签页都有子页面,返回该标签页时会保留最后访问的页面,再次点击该标签页则回到父页面。此效果在React Native中可通过Stack Navigator轻松实现,请问如何通过GetX路由在Flutter中实现该功能?
我曾在应用中尝试使用IndexedStack,但未达到预期效果,希望通过命名路由实现。
基于GetX的实现方案
核心思路是给每个底部标签页分配独立的路由栈,通过自定义底部导航栏的点击逻辑,实现「切换标签保留栈状态、重复点击回到栈根页面」的效果。
1. 配置多栈路由
在GetX路由配置中,为每个标签页创建嵌套栈,包含该标签的根页面和所有子页面:
List<GetPage> routes = [ // 首页栈 GetPage( name: '/home', page: () => HomeScreen(), children: [ GetPage(name: '/home/detail', page: () => HomeDetailScreen()), ], ), // 发现页栈 GetPage( name: '/discover', page: () => DiscoverScreen(), children: [ GetPage(name: '/discover/detail', page: () => DiscoverDetailScreen()), ], ), // 我的页栈 GetPage( name: '/profile', page: () => ProfileScreen(), children: [ GetPage(name: '/profile/setting', page: () => SettingScreen()), ], ), ];
2. 自定义底部导航栏逻辑
用IndexedStack保持未选中标签的页面状态,结合GetNavigator为每个标签绑定独立栈,再通过点击事件处理两种逻辑:
class MainScreen extends StatefulWidget { @override _MainScreenState createState() => _MainScreenState(); } class _MainScreenState extends State<MainScreen> { int _currentIndex = 0; // 标记每个标签栈是否已初始化 final List<bool> _stackInited = [false, false, false]; // 每个标签对应的根路由 final List<String> _rootRoutes = ['/home', '/discover', '/profile']; @override Widget build(BuildContext context) { return Scaffold( body: IndexedStack( index: _currentIndex, children: [ // 每个子项对应一个标签的独立路由栈 GetNavigator(key: Get.nestedKey(0)), GetNavigator(key: Get.nestedKey(1)), GetNavigator(key: Get.nestedKey(2)), ], ), bottomNavigationBar: BottomNavigationBar( currentIndex: _currentIndex, items: const [ BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'), BottomNavigationBarItem(icon: Icon(Icons.explore), label: '发现'), BottomNavigationBarItem(icon: Icon(Icons.person), label: '我的'), ], onTap: (index) { if (index == _currentIndex) { // 重复点击当前标签,回到该栈的根页面 Get.until((route) => route.settings.name == _rootRoutes[index]); } else { setState(() => _currentIndex = index); // 未初始化的栈,先跳转到根页面 if (!_stackInited[index]) { Get.toNamed(_rootRoutes[index], id: index); _stackInited[index] = true; } } }, ), ); } }
3. 子页面跳转规则
在标签根页面跳转到子页面时,必须指定对应栈的ID(即标签索引),确保路由进入正确的栈:
// 首页跳转到详情页 Get.toNamed('/home/detail', id: 0); // 发现页跳转到详情页 Get.toNamed('/discover/detail', id: 1);
关键细节说明
Get.nestedKey为每个栈分配独立标识,保证不同标签的路由状态互不干扰IndexedStack避免切换标签时重建页面,保留未选中标签的栈状态Get.until通过判断路由名称,精准回到当前栈的根页面
内容的提问来源于stack exchange,提问作者Hassan Amjad
相关产品推荐
相关产品推荐

