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
相关产品推荐
相关产品推荐

