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
相关产品推荐
相关产品推荐

