Flutter根据用户角色切换底部导航栏报Null类型不匹配错误
报错根因
你碰到的type 'Null' is not a subtype of type 'List<BottomNavigationBarItem>'错误,本质是三个代码逻辑问题:
- 你写的
showScreens()、showButtons()两个方法,所有判断分支里都没加return关键字。Dart语法里,如果函数没有显式写return返回值,默认会返回null,BottomNavigationBar的items参数接收到null自然会报类型不匹配的错误。你之前在else分支加按钮没生效,也是因为没写return,加的代码根本没有被返回给组件使用。 showButtons()的else分支原来返回的是Center组件,和items要求的List<BottomNavigationBarItem>类型完全不匹配,就算加了return也会触发类型错误。- 还有个隐藏bug:不同角色对应的导航按钮数量不一样,如果用户切换角色时,之前保存的
currentIndex超过新角色导航栏的最大索引,会触发列表越界报错。
修复后完整代码
把原有代码替换为以下版本即可:
class SkoolWorkshopApp extends StatefulWidget { const SkoolWorkshopApp({Key? key, required this.rol}) : super(key: key); final String rol; @override _SkoolWorkshopAppState createState() => _SkoolWorkshopAppState(); } class _SkoolWorkshopAppState extends State<SkoolWorkshopApp> { int currentIndex = 0; // 监听角色变化,重置导航索引避免越界 @override void didUpdateWidget(covariant SkoolWorkshopApp oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.rol != widget.rol) { setState(() { currentIndex = 0; }); } } final TeacherScreens = [ HomePage(), awaitingProfile(), awaitingProfile(), NotificationPage(), singleProfilePage(), ]; final EmployeeScreens = [ HomePage(), NotificationPage(), ProfilePage(), ]; final TeacherButtons = [ BottomNavigationBarItem( icon: Icon(Icons.home), label: 'Home', ), BottomNavigationBarItem( icon: Icon(Icons.check), label: 'Bevestigd', ), BottomNavigationBarItem( icon: Icon(Icons.access_time), label: 'Afwachting', ), BottomNavigationBarItem( icon: Icon(Icons.circle_notifications_outlined), label: 'Meldingen', ), BottomNavigationBarItem( icon: Icon(Icons.account_circle_outlined), label: 'Profiel', ), ]; final EmployeeButtons = [ BottomNavigationBarItem( icon: Icon(Icons.home), label: 'Home', ), BottomNavigationBarItem( icon: Icon(Icons.circle_notifications_outlined), label: 'Meldingen', ), BottomNavigationBarItem( icon: Icon(Icons.account_circle_outlined), label: 'Profielen', ), ]; // 显式声明返回类型为Widget,所有分支补全return Widget showScreens() { if(widget.rol == "Docent") { return TeacherScreens[currentIndex]; } else if(widget.rol == "Medewerker") { return EmployeeScreens[currentIndex]; } else { return const Center(child: Text("角色权限异常")); } } // 显式声明返回类型为导航按钮列表,所有分支补全return List<BottomNavigationBarItem> showButtons() { if(widget.rol == "Docent") { return TeacherButtons; } else if(widget.rol == "Medewerker") { return EmployeeButtons; } else { // 错误场景兜底返回符合类型要求的按钮组,不返回Widget return [ const BottomNavigationBarItem( icon: Icon(Icons.error), label: '配置错误', ) ]; } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: backgroundColor, body: showScreens(), bottomNavigationBar: BottomNavigationBar( type: BottomNavigationBarType.fixed, backgroundColor: mainColor, selectedItemColor: Colors.black, currentIndex: currentIndex, onTap: (index) => setState(() => currentIndex = index), items: showButtons(), ), ); } }
核心修改点
- 给两个工具方法显式声明返回值类型,避免隐式类型推断带来的问题
- 所有判断分支都补全了
return关键字,解决默认返回null的核心报错 - 修正了
showButtons方法else分支的返回值类型,兜底返回符合要求的导航按钮,不再返回不匹配的Widget组件 - 新增角色变化监听逻辑,切换角色时自动重置导航选中索引,解决列表越界隐患
内容的提问来源于stack exchange,提问作者Sheets
相关产品推荐
相关产品推荐

