Flutter中ListView.builder报错:期望(Object)=>Widget类型却获(String)=>SizedBox
错误提示 Expected a value of type '(Object) => Widget', but got one of type '(String) => SizedBox' 的核心原因:ListViewColumn<T> 作为泛型组件,要求传入的 itemList 中所有 ListModel 的泛型类型必须统一。但在 AnyPage 里,你传入了两个不同泛型类型的 ListModel(一个绑定 String,一个绑定 DateTime),导致 Dart 自动将 T 推断为 Object。此时 ListViewColumn 期望 cell 的类型是 (Object) => Widget,但你提供的是针对具体类型的函数(比如 (String) => SizedBox),两者类型不兼容,因此触发报错。
将 ListViewColumn 改为非泛型组件,让它支持多种类型的 ListModel,具体修改如下:
1. 修改 ListViewColumn 类
移除泛型约束,将 itemList 类型改为 List<ListModel<dynamic>>:
class ListViewColumn extends StatelessWidget { const ListViewColumn({ required this.itemList, Key? key, }) : super(key: key); // 改为接受动态类型的ListModel列表 final List<ListModel<dynamic>> itemList; @override Widget build(BuildContext context) { return Column( children: [ Row( children: [ ...itemList.map( (e) => Column( children: [ if (e.columnHeaderCell != null) e.columnHeaderCell!(e.columnName ?? '') else Text(e.columnName ?? ''), SizedBox( width: 100.pw, height: 100.pw, child: ListView.builder( itemCount: e.list.length, itemBuilder: (BuildContext context, int index) => e.cell(e.list[index]), ), ), ], ), ), ], ), ], ); } }
2. 保留 ListModel 泛型
ListModel 依然保留泛型,用来约束自身的列表和cell函数类型:
class ListModel<T> { ListModel({ required this.list, required this.cell, this.columnName, this.columnHeaderCell, }); final String? columnName; final List<T> list; final Widget Function(T value) cell; final Widget Function(String value)? columnHeaderCell; }
3. AnyPage 代码无需调整
原来的 AnyPage 中创建的 ListModel<String> 和 ListModel<DateTime> 可以直接赋值给 List<ListModel<dynamic>>,Dart 会自动处理类型兼容。
如果需要更严格的类型安全,可以创建抽象基类来统一不同类型的 ListModel,但当前场景下上述修改已经足够解决问题,且实现简单直接。
内容的提问来源于stack exchange,提问作者Andreas Meggetto

