Flutter底部导航栏问题:索引计数器在Scaffold中的正确放置
Flutter底部导航栏修复方案
问题根源
你的代码存在三个核心问题导致导航失效:
- build方法内重新声明了
_selectedIndex局部变量,覆盖了类成员变量,点击导航项时更新的是局部变量而非状态变量,导致UI不刷新 - 导航栏有4个目标页,但
pages数组仅定义了3个页面,索引不匹配 - body区域未根据选中索引切换对应页面,始终显示固定内容
修复后的完整代码
class LevelSelectionScreen extends StatefulWidget { const LevelSelectionScreen({super.key}); @override _LevelSelectionScreenState createState() => _LevelSelectionScreenState(); } class _LevelSelectionScreenState extends State<LevelSelectionScreen> { int _selectedIndex = 0; void _onItemTapped(int index) { setState(() { _selectedIndex = index; }); } @override Widget build(BuildContext context) { final playerProgress = context.watch<PlayerProgress>(); // 移除局部变量声明,使用类成员变量维护选中状态 final pages = [ const MainMenuScreen(), const AvailabilityScreen(), const SettingsScreen(), // 补充第四个页面,与导航项数量匹配 const ProfileScreen(), ]; return Scaffold( extendBody: true, bottomNavigationBar: NavigationBar( height: 60, selectedIndex: _selectedIndex, elevation: 100, onDestinationSelected: _onItemTapped, destinations: [ NavigationDestination( icon: const Icon(Icons.home_outlined), // 未选中用轮廓图标 selectedIcon: const Icon(Icons.home), // 选中用填充图标,区分高亮状态 label: 'home', ), NavigationDestination( icon: const Icon(Icons.book_outlined), selectedIcon: const Icon(Icons.book), label: 'learn', ), NavigationDestination( icon: const Icon(Icons.gamepad_outlined), selectedIcon: const Icon(Icons.gamepad), label: 'play', ), NavigationDestination( icon: const Icon(Icons.person_outlined), selectedIcon: const Icon(Icons.person), label: 'profile', ), ], ), backgroundColor: const Color(0XFFFEF4DF), // 根据选中索引切换页面内容 body: pages[_selectedIndex], ); } }
关键修复说明
- 移除局部变量覆盖:删除build方法内的
int _selectedIndex = 0;,确保使用类成员变量维护选中状态,点击后setState能正确触发UI刷新 - 匹配页面与导航项数量:在
pages数组中补充第四个页面(示例为ProfileScreen),保证导航项索引与页面数组索引一一对应,避免索引越界 - 动态切换body内容:将原来固定的
ResponsiveScreen替换为pages[_selectedIndex],实现选中导航项时自动切换对应页面 - 优化高亮视觉:将未选中图标改为轮廓样式,选中时用填充图标,让高亮状态更直观
如果需要保留原LevelSelectionScreen的内容作为其中一个导航选项,可将其加入pages数组,例如:
final pages = [ const MainMenuScreen(), const AvailabilityScreen(), const SettingsScreen(), LevelSelectionScreen(), // 将当前页面作为第四个导航选项 ];
内容的提问来源于stack exchange,提问作者Elena Epshtein
相关产品推荐
相关产品推荐

