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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 02:15:33