如何修复_TypeError:'List<Animal?>'不是'List<Animal>?'的子类型
Flutter多选组件类型不匹配错误修复方案
核心问题分析
报错TypeError (type 'List<Animal?>' is not a subtype of type 'List<Animal>?' of 'value')的本质是类型定义不匹配:
- 你使用的
MultiSelectBottomSheetField泛型为Animal,因此它的onConfirm回调返回的是List<Animal>?(可选的非空Animal列表) - 但你错误地将回调参数声明为
List<Animal?>?,同时把状态变量_selectedAnimals3也定义成了List<Animal?>?,导致类型无法兼容
分步修复
1. 修正状态变量类型
把_selectedAnimals3的类型从可空元素列表改为非空元素的可选列表:
List<Animal>? _selectedAnimals3 = [];
2. 修正onConfirm回调参数
将回调参数类型改为List<Animal>?,直接赋值给状态变量:
onConfirm: (List<Animal>? values) { setState(() { _selectedAnimals3 = values; }); _multiSelectKey.currentState?.validate(); }
3. 移除validator中的冗余空断言
由于values已通过非空判断,map遍历的元素无需强制空断言:
validator: (values) { if (values == null || values.isEmpty) { return "Required"; } List<String> names = values.map((e) => e.name).toList(); if (names.contains("Frog")) { return "Frogs are weird!"; } return null; },
4. 修正初始化逻辑
用List.from创建新列表,避免直接引用原数据列表:
@override void initState() { _selectedAnimals3 = List.from(_animals); super.initState(); }
5. 修正Chip点击移除逻辑
对状态变量做安全判空处理:
chipDisplay: MultiSelectChipDisplay( onTap: (item) { setState(() { _selectedAnimals3?.remove(item); }); _multiSelectKey.currentState?.validate(); }, ),
完整修复代码
class _ParticipantsToSelectState extends State<ParticipantsToSelect> { static List<Animal> _animals = [ Animal(id: 1, name: "Lion"), Animal(id: 2, name: "Flamingo"), Animal(id: 3, name: "Hippo"), Animal(id: 4, name: "Horse"), Animal(id: 5, name: "Tiger"), Animal(id: 6, name: "Penguin"), Animal(id: 7, name: "Spider"), Animal(id: 8, name: "Snake"), Animal(id: 9, name: "Bear"), Animal(id: 10, name: "Beaver"), ]; final _items = _animals .map((animal) => MultiSelectItem<Animal>(animal, animal.name)) .toList(); List<Animal>? _selectedAnimals3 = []; final _multiSelectKey = GlobalKey<FormFieldState<List<Animal>?>>(); @override void initState() { _selectedAnimals3 = List.from(_animals); super.initState(); } @override Widget build(BuildContext context) { return Expanded( child: MultiSelectBottomSheetField<Animal>( key: _multiSelectKey, initialChildSize: 0.7, maxChildSize: 0.95, title: Text("Animals"), buttonText: Text("Favorite Animals"), items: _items, searchable: true, validator: (values) { if (values == null || values.isEmpty) { return "Required"; } List<String> names = values.map((e) => e.name).toList(); if (names.contains("Frog")) { return "Frogs are weird!"; } return null; }, onConfirm: (List<Animal>? values) { setState(() { _selectedAnimals3 = values; }); _multiSelectKey.currentState?.validate(); }, chipDisplay: MultiSelectChipDisplay( onTap: (item) { setState(() { _selectedAnimals3?.remove(item); }); _multiSelectKey.currentState?.validate(); }, ), ), ); } }
内容的提问来源于stack exchange,提问作者martin sanzoo
相关产品推荐
相关产品推荐

