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

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'


报错原因

  1. API请求函数未指定泛型返回类型:fetchUsers()的返回类型写为Future<List>,Dart会默认推断为Future<List<dynamic>>,导致FutureBuilder的snapshot.data类型为List<dynamic>?,无法直接匹配dataSource要求的List<User>类型。
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 03:30:47