Flutter跨类访问spoonacular接口返回的reciepeList为空如何解决
问题原因
- 你在initState中只实例化了
GetRecipies类,没有调用请求数据的异步方法getReciepe() getReciepe()是异步方法,即使你调用了它,如果没有用await等待请求完成就直接访问reciepeList,此时网络请求还没返回结果,列表自然是空的- 数据请求完成后没有触发Flutter的UI重绘,就算列表有数据界面也不会更新
修复方案
按如下步骤修改main.dart代码即可:
- 将
GetRecipies实例定义为State类的全局成员,不要放在initState内做局部声明 - 封装独立的异步加载方法,等待网络请求完成后调用
setState触发UI更新 - 增加加载状态处理,给ListView指定itemCount属性
修改后完整main.dart代码参考:
import 'package:flutter/material.dart'; import 'package:spponacular/services.dart'; void main() { runApp(MaterialApp( home: Home(), )); } class Home extends StatefulWidget { const Home({ Key? key }) : super(key: key); @override _HomeState createState() => _HomeState(); } class _HomeState extends State<Home> { // 声明请求类实例为全局成员 GetRecipies recipeService = GetRecipies(); // 加载状态标记用于显示占位UI bool isLoading = true; @override void initState() { super.initState(); loadRecipeData(); } // 封装异步加载方法 Future<void> loadRecipeData() async { // 等待网络请求完成 await recipeService.getReciepe(); // 页面挂载的情况下更新状态触发重绘 if(mounted){ setState((){ isLoading = false; }); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Colors.deepPurpleAccent, title: const Text('Recipes'), ), body: isLoading ? const Center(child: CircularProgressIndicator()) : ListView.builder( itemCount: recipeService.reciepeList.length, itemBuilder: (context,index){ final currentRecipe = recipeService.reciepeList[index]; return ListTile( leading: Image.network(currentRecipe.image, width: 50, height: 50, fit: BoxFit.cover), title: Text(currentRecipe.name), subtitle: Text("热量:${currentRecipe.calories} | 碳水:${currentRecipe.carbs} | 蛋白质:${currentRecipe.protein}"), ); } ), ); } }
补充优化建议:可以给
getReciepe()方法加上返回值,直接返回请求到的食谱列表,减少对类成员变量的依赖,代码耦合度会更低。
内容的提问来源于stack exchange,提问作者Divya
相关产品推荐
相关产品推荐

