Flutter PaginatedDataTable结合JSON API报错:Object?无法转为List<User>
问题:Flutter中FutureBuilder传递数据源时类型不匹配报错
在使用PaginatedDataTable展示API获取的用户数据时,source: dataSource(snapshot.data)抛出类型错误:The argument type 'Object?' can't be assigned to the parameter type 'List
报错原因
- API请求函数未指定泛型返回类型:
fetchUsers()的返回类型写为Future<List>,Dart会默认推断为Future<List<dynamic>>,导致FutureBuilder的snapshot.data类型为List<dynamic>?,无法直接匹配dataSource要求的List<User>类型。 - FutureBuilder未声明泛型参数:未明确
FutureBuilder的泛型类型时,snapshot.data的默认类型是Object?,进一步触发类型不兼容的报错。
修复步骤
1. 修正API请求函数的返回类型
将fetchUsers()的返回类型从Future<List>改为Future<List<User>>,明确返回的是User对象列表:
import 'package:http/http.dart' as http; import '../user_model.dart'; Future<List<User>> fetchUsers() async { Uri url = Uri.parse("https://jsonplaceholder.typicode.com/users"); final response = await http.get(url); return usersFromJson(response.body); }
2. 给FutureBuilder指定泛型参数
在FutureBuilder声明时添加<List<User>>,让Dart正确推断snapshot.data的类型:
FutureBuilder<List<User>>( future: fetchUsers(), builder: (context, snapshot) { if (snapshot.hasData) { return Column( children: [ PaginatedDataTable( sortColumnIndex: sortColumnIndex, sortAscending: isAscending, columns: [ DataColumn(label: const Text("Id"), onSort: onSort), DataColumn(label: const Text("Name"), onSort: onSort), DataColumn(label: const Text("Username"), onSort: onSort), DataColumn(label: const Text("Email"), onSort: onSort), DataColumn(label: const Text("Roles"), onSort: onSort), DataColumn(label: const Text("Actions"), onSort: onSort), ], header: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "Manage Users", style: TextStyle( fontSize: width * 0.04, fontWeight: FontWeight.normal), ), MaterialButton( onPressed: () { showMaterialModalBottomSheet( context: context, builder: (context) => SizedBox( height: height * 0.9, child: BottomSheetWidget(), ), shape: const RoundedRectangleBorder( borderRadius: BorderRadius.only( topLeft: Radius.circular(15), topRight: Radius.circular(15)))); }, color: const Color.fromRGBO(30, 119, 66, 1), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), child: Text( "Add User", style: TextStyle( color: Colors.white, fontSize: width * 0.03), ), ) ], ), source: dataSource(snapshot.data!) ) ], ); } else if (snapshot.hasError) { return Text("${snapshot.error}"); } return const Center(child: CircularProgressIndicator()); })
补充说明
因为已经通过snapshot.hasData确认数据存在,所以可以安全使用!做非空断言;如果追求更严谨的写法,也可以用snapshot.data as List<User>做类型转换,前者在已做空检查的场景下更简洁。
内容的提问来源于stack exchange,提问作者Mohammed Bekele
相关产品推荐
相关产品推荐

