Flutter如何合并多个JSON数据并在FutureBuilder的ListView中使用
Flutter多份JSON数据合并方案
两份JSON合并实现
核心逻辑:不能直接拼接http响应对象,需要先分别解码两个响应的JSON内容,再根据业务需求合并。你当前使用的两个古兰经API返回结构一致,分别对应文本和音频资源,推荐将两个解码后的结果存入同一个Map中,方便后续在ListView中关联使用,修改后代码如下:
var data; Future<void> getAll() async{ // 文本JSON请求 final url1 = "http://api.alquran.cloud/v1/quran/en.asad"; Uri myUri1 = Uri.parse(url1); final response1 = await http.get(myUri1); // 音频JSON请求 final url2 = "http://api.alquran.cloud/v1/quran/ar.alafasy"; Uri myUri2 = Uri.parse(url2); final response2 = await http.get(myUri2); // 先判断两个请求都成功 if (response1.statusCode == 200 && response2.statusCode == 200) { // 分别解码两份JSON final textJson = json.decode(response1.body); final audioJson = json.decode(response2.body); // 合并为一个Map,也可以根据业务需要合并列表 data = { "textData": textJson, "audioData": audioJson }; } else { throw Exception('Failed to load resources'); } }
如果你的业务场景是两份JSON为同结构列表,需要合并为一个大列表使用,将合并部分替换为以下代码即可:
data = [...textJson['data']['surahs'], ...audioJson['data']['surahs']];
提示:如果你需要将同源不同类型的资源(比如同一章节的文本和音频)一一对应使用,不要直接合并列表,建议保留Map结构,通过公共的唯一标识(比如章节编号)来关联两个资源的对应条目,避免顺序错乱导致数据不匹配。
两份以上JSON的合并方案
如果需要合并N份JSON,推荐用Future.wait批量发起异步请求,减少冗余代码,示例如下:
var data; Future<void> getAll() async{ // 把所有请求的URL统一放到列表里 final List<String> apiUrls = [ "http://api.alquran.cloud/v1/quran/en.asad", "http://api.alquran.cloud/v1/quran/ar.alafasy", // 可以继续添加更多API地址 ]; // 批量发起请求,等待所有请求完成 final responses = await Future.wait( apiUrls.map((url) => http.get(Uri.parse(url))) ); // 校验所有请求都成功 final allSuccess = responses.every((res) => res.statusCode == 200); if(allSuccess) { // 解码所有JSON后合并,这里按存储为Map的示例,key用索引区分 final Map<String, dynamic> mergedData = {}; for(int i=0; i<responses.length; i++) { mergedData["resource_$i"] = json.decode(responses[i].body); } data = mergedData; // 如果是合并列表的场景,用下面的代码 // final List mergedList = []; // for(final res in responses) { // final jsonData = json.decode(res.body); // mergedList.addAll(jsonData['data']['surahs']); // } // data = mergedList; } else { throw Exception('部分资源加载失败'); } }
合并后你在FutureBuilder的ListView.builder里可以直接通过对应key取对应资源,比如要取文本内容用data['textData'],取音频资源用data['audioData'],按需关联对应章节的内容即可。
内容的提问来源于stack exchange,提问作者Mohammed Bekele
相关产品推荐
相关产品推荐

