Flutter自定义泛型下拉组件onSelected回调类型不匹配异常如何解决?
问题原因
错误的核心是泛型参数没有在State类中正确传递,导致运行时类型不匹配:
你定义的_LabelDropdownState继承State时,没有给关联的LabelDropdown传入泛型参数,默认会被推断为LabelDropdown<dynamic>,所以State中访问的widget.onSelected类型是Function(dynamic),和你外部传入的Function(String)类型不匹配,触发类型转换异常。
修复步骤
需要修改2处代码:
- 修正State类的继承声明,给父组件传递泛型:
将
class _LabelDropdownState<T> extends State<LabelDropdown>
改为
class _LabelDropdownState<T> extends State<LabelDropdown<T>>
- 修正
createState方法的返回值,绑定对应泛型:
将
_LabelDropdownState createState() => _LabelDropdownState();
改为
_LabelDropdownState<T> createState() => _LabelDropdownState<T>();
可选优化:调用onSelected前做空判断,避免用户未传回调时的空安全异常:
将widget.onSelected!(value);改为widget.onSelected?.call(value);
完整修复后代码
import 'package:flutter/material.dart'; class LabelDropdown<T> extends StatefulWidget { const LabelDropdown({ Key? key, required this.label, required this.list, this.onSelected, }) : super(key: key); final String label; final List<T> list; final Function(T value)? onSelected; @override _LabelDropdownState<T> createState() => _LabelDropdownState<T>(); } class _LabelDropdownState<T> extends State<LabelDropdown<T>> { late T _selected = widget.list[0]; @override Widget build(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(widget.label), DropdownButton<T>( value: _selected, onChanged: (value) { setState(() { _selected = value!; widget.onSelected?.call(value); }); }, items: widget.list .map( (value) => DropdownMenuItem<T>( value: value, child: Text(value.toString()), ), ) .toList(), ), ], ); } } main() => runApp( MaterialApp( home: Scaffold( body: SafeArea( child: LabelDropdown<String>( label: 'Label', list: const ['One', 'Two'], onSelected: (value) { print(value); }, ), ), ), ), );
内容的提问来源于stack exchange,提问作者Burhan Khanzada
相关产品推荐
相关产品推荐

