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

Flutter中FutureBuilder仅显示加载进度框不展示API数据问题

Flutter ListView 一直显示加载指示器问题定位

核心问题点

你的代码存在5处问题,导致接口虽然控制台能打印返回数据,但FutureBuilder永远拿不到完成信号,一直显示加载框:

  • 接口请求函数无有效返回值:signInData() 中200成功分支下,所有将响应解析为List<Autogenerated>并返回的代码全部被注释,函数末尾的return null也被注释,请求执行完成后没有给Future返回任何结果。
  • 500分支递归调用未返回结果:触发token刷新逻辑重新调用signInData()时,没有加return关键字,就算刷新token后请求成功,结果也无法传递到外层调用方。
  • 异常被静默吞掉:catch块仅打印错误日志,没有重新抛出异常,就算请求过程报错,FutureBuilder也收不到错误通知,永远不会进入错误展示分支。
  • API实例未初始化:ResultsPage中定义的_APIState? api;从未赋值,正常情况下api?.signInData()根本不会触发请求,如果你控制台能看到接口打印日志,说明运行代码和贴出的代码有出入,这个是潜在空指针隐患。
  • 额外冗余操作:你写的jsonDecode(json.encode(response.data))属于多余逻辑,dio默认已经将响应体解码为Dart可识别的List/Map结构,不需要重复编解码浪费性能。

修复后代码

接口请求部分

Future<List<Autogenerated>> signInData() async {
    final prefs = await SharedPreferences.getInstance();
    final String? token = prefs.getString('token');

    try {
      Response response = await _dio.post('$_baseUrl/api/gateway',
          data: {
            "ClientPackageId": "0cdd231a-d7ad-4a68-a934-d373affb5100",
            "PlatformId": "ios",
            "ClientUserId": "AhmedOmar",
            "VinNumber": VINumber
          },
          options: Options(
            headers: {
              "Content-Type": "application/json;charset=UTF-8",
              "Charset": 'utf-8',
              "Authorization": "Bearer $token",
            },
          ));
      print("接口响应:${response.statusCode}");
      print(response.data);
      
      if (response.statusCode == 200) {
        // 直接解析数据返回,去掉多余编解码
        return List<Autogenerated>.from(
          response.data.map((item) => Autogenerated.fromJson(item))
        );
      } else if (response.statusCode == 500) {
        await getToken();
        // 递归调用必须return,否则结果无法传递
        return signInData();
      } else {
        throw Exception('请求失败,状态码:${response.statusCode}');
      }
    } catch (e) {
      print("请求异常:$e");
      // 必须重新抛出异常,让上层感知错误
      rethrow;
    }
  }

列表页面部分

class ResultsPage extends StatefulWidget {
  const ResultsPage({Key? key}) : super(key: key);

  @override
  _ResultsPageState createState() => _ResultsPageState();
}

class _ResultsPageState extends State<ResultsPage> {
  late Future<List<Autogenerated>> objectList;
  // 替换成你实际的API类实例,不要用空类型不赋值
  final yourApiInstance = _APIState();

  @override
  void initState() {
    super.initState();
    objectList = yourApiInstance.signInData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: FutureBuilder<List<Autogenerated>>(
          future: objectList,
          builder: (context, snapshot) {
            // 先判断请求是否完成
            if (snapshot.connectionState == ConnectionState.done) {
              if (snapshot.hasData) {
                final dataList = snapshot.data!;
                return Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: ListView.builder(
                      itemCount: dataList.length,
                      itemBuilder: (context, index) {
                        final item = dataList[index];
                        return Card(
                          shape: RoundedRectangleBorder(
                            side: BorderSide(
                              color: Colors.green.shade300,
                            ),
                            borderRadius: BorderRadius.circular(15.0),
                          ),
                          child: ListTile(
                            leading: Text(item.category),
                            title: Text(item.category),
                            subtitle: Text('${item.category}\n${item.category}'),
                            trailing: Text(item.category),
                          ),
                        );
                      },
                    ));
              }
              // 错误分支
              if (snapshot.hasError) {
                return Center(child: Text('加载失败:${snapshot.error}'));
              }
            }
            // 请求未完成时显示加载框
            return const Center(child: CircularProgressIndicator());
          },
        ));
  }
}

内容的提问来源于stack exchange,提问作者SaDev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 09:51:46