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

Flutter自定义泛型下拉组件onSelected回调类型不匹配异常如何解决?

问题原因

错误的核心是泛型参数没有在State类中正确传递,导致运行时类型不匹配:
你定义的_LabelDropdownState继承State时,没有给关联的LabelDropdown传入泛型参数,默认会被推断为LabelDropdown<dynamic>,所以State中访问的widget.onSelected类型是Function(dynamic),和你外部传入的Function(String)类型不匹配,触发类型转换异常。

修复步骤

需要修改2处代码:

  1. 修正State类的继承声明,给父组件传递泛型:
    将
class _LabelDropdownState<T> extends State<LabelDropdown>

改为

class _LabelDropdownState<T> extends State<LabelDropdown<T>>
  1. 修正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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 23:57:00