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

Dart使用BottomNavigationBar时列表类型定义错误的解决方法

问题

作为Dart新手,在使用BottomNavigationBar组件时,想给关联的页面列表添加标题,于是定义了如下列表:

final List<Map<String, dynamic>> _pages = [
    const {'page': CategoriesScreen(), 'title': 'Categories'},
    const {'page': FavouritesScreen(), 'title': "Favourite"}
];

使用时通过body: _pages[_selectedPageIndex]['page'] as Widget调用,却出现错误:

type 'List' is not a subtype of type 'List<Map<String, dynamic>>' of 'function result'

复现问题的Scaffold代码:

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: const Text('Meals'),
    ),
    body: _pages[_selectedPageIndex]['page'] as Widget,
    bottomNavigationBar: BottomNavigationBar(
      onTap: _selectPage,
      backgroundColor: Theme.of(context).colorScheme.primary,
      unselectedItemColor: Colors.white,
      currentIndex: _selectedPageIndex,
      // type: BottomNavigationBarType.fixed,
      selectedItemColor: Theme.of(context).colorScheme.secondary,
      items: [
        BottomNavigationBarItem(
          backgroundColor: Theme.of(context).colorScheme.primary,
          icon: const Icon(Icons.category),
          label: 'Categories',
        ),
        BottomNavigationBarItem(
          backgroundColor: Theme.of(context).colorScheme.primary,
          icon: const Icon(Icons.star),
          label: 'Favourites',
        ),
      ],
    ),
  );
}

请问该如何正确定义这个列表的类型?

解决方案

问题根源在于你给列表内的Map加了const修饰,但CategoriesScreen()和FavouritesScreen()是Widget实例,无法被编译时常量化(除非这两个Widget本身是const构造且满足常量条件),导致Dart无法正确推断列表类型,进而抛出类型不匹配错误。

你可以通过以下两种方式解决:

  • 移除列表项的const修饰
    直接去掉Map前的const,让Dart自动推断正确类型:

    final List<Map<String, dynamic>> _pages = [
        {'page': CategoriesScreen(), 'title': 'Categories'},
        {'page': FavouritesScreen(), 'title': "Favourite"}
    ];
    
  • 用自定义类替代Map(更推荐)
    用类型安全的自定义类存储页面和标题,避免dynamic类型带来的潜在问题:

    // 定义页面数据类
    class PageItem {
      final Widget page;
      final String title;
    
      PageItem({required this.page, required this.title});
    }
    
    // 定义列表
    final List<PageItem> _pages = [
      PageItem(page: CategoriesScreen(), title: 'Categories'),
      PageItem(page: FavouritesScreen(), title: 'Favourite'),
    ];
    
    // 使用时无需类型转换
    body: _pages[_selectedPageIndex].page,
    

如果你的CategoriesScreen和FavouritesScreen支持const构造(类为immutable、所有成员为final、构造器加const),也可以保留const:

// 示例const构造的页面Widget
class CategoriesScreen extends StatelessWidget {
  const CategoriesScreen({super.key});
  // 其他实现代码
}

// 此时列表可定义为const
final List<Map<String, dynamic>> _pages = const [
    {'page': CategoriesScreen(), 'title': 'Categories'},
    {'page': FavouritesScreen(), 'title': "Favourite"}
];

内容的提问来源于stack exchange,提问作者kyrolos magdy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 13:55:19