Flutter空安全迁移后Dart闭包返回类型不匹配报错如何解决?
Flutter 2空安全迁移闭包返回类型不匹配问题修复方案
错误原因
PopupMenuButton的itemBuilder要求闭包返回List<PopupMenuEntry<dynamic>>类型的非空集合,你的代码存在两处不匹配:
- map闭包内仅满足
if条件时才返回PopupMenuItem,不满足条件时无显式返回,默认返回null,导致map生成的元素是可空类型PopupMenuItem<dynamic>? - 最终生成的列表为
List<PopupMenuItem<dynamic>?>,和要求的非空List<PopupMenuEntry<dynamic>>类型不匹配
修复方案
方案1(推荐):先过滤符合条件的元素再映射
先筛选出满足条件的菜单项,再转换为PopupMenuItem,全程不会产生null值:
Widget _parentMenuSelector() { return PopupMenuButton<dynamic>( child: Padding( padding: const EdgeInsets.all(16.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Icon(Icons.content_copy), Text('Copy to another menu'), ], ), ), onSelected: (dynamic selectedMenu) { Map<String, dynamic> selMenu = selectedMenu; print(selMenu['id']); model!.copyMenuItem(selMenu['id']); }, itemBuilder: (BuildContext context) { return model!.restaurant!.restaurantMenus!.values .where((dynamic item) { Map<String, dynamic> itemMap = item; return itemMap['name'] != model!.menu!.name; }) .map((dynamic item) { Map<String, dynamic> itemMap = item; return PopupMenuItem<dynamic>( child: Text('Copy to ${itemMap['name']}'), value: item, ); }) .toList(); }, ); }
方案2:映射后过滤空值
如果你不想拆分判断逻辑,也可以在map生成可空集合后,过滤掉所有null值:
itemBuilder: (BuildContext context) { return model!.restaurant!.restaurantMenus!.values .map<PopupMenuEntry<dynamic>?>((dynamic item) { Map<String, dynamic> itemMap = item; if (itemMap['name'] != model!.menu!.name) { return PopupMenuItem<dynamic>( child: Text('Copy to ${itemMap['name']}'), value: item, ); } return null; }) .whereType<PopupMenuEntry<dynamic>>() .toList(); },
注意事项
代码中大量使用!强制解包空安全字段,需要确保model、restaurant、restaurantMenus、menu这些字段运行时一定不为空。如果存在为空的可能性,建议用?.搭配默认空集合处理,避免运行时空异常。
内容的提问来源于stack exchange,提问作者Ernesto
相关产品推荐
相关产品推荐

