Flutter使用FutureBuilder加载本地JSON文件不显示数据如何解决
问题原因
- FutureBuilder使用逻辑错误:你传入的
getPlantsLocally()方法无返回值,FutureBuilder无法准确感知异步任务的执行结果,且该方法内通过setState更新外部列表的逻辑和FutureBuilder的使用场景冲突,同时未捕获异步过程中的异常,报错后直接进入默认分支显示错误页面。 - JSON格式不合法:你提供的JSON示例末尾存在多余逗号,且数组、外层对象未正确闭合,
json.decode执行时会直接抛出解析异常。 - 大概率未注册assets资源:如果没有在
pubspec.yaml的flutter节点下声明JSON文件的资源路径,DefaultAssetBundle无法读取到本地文件,会直接抛出资源不存在异常。
修正方案
1. 调整异步加载逻辑
修改getPlantsLocally方法,直接返回解析后的植物列表,不在方法内部执行setState:
Future<List<Plants>> getPlantsLocally() async { final assetBundle = DefaultAssetBundle.of(context); final data = await assetBundle.loadString('assets/plants.json'); final body = json.decode(data); final list = body["plant"] as List<dynamic>; return list.map((e) => Plants.fromJson(e)).toList(); }
2. 修正FutureBuilder实现
增加异常捕获逻辑,直接从snapshot中获取加载完成的数据:
@override Widget build(BuildContext context) => Scaffold( body: FutureBuilder<List<Plants>>( future: getPlantsLocally(), builder:(context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } // 打印错误信息方便排查问题 if (snapshot.hasError) { return Center(child: Text('加载失败: ${snapshot.error}')); } if (snapshot.hasData && snapshot.data!.isNotEmpty) { final planty = snapshot.data!; return Container( height: 200, child: ListView.builder( itemCount: planty.length, itemBuilder: (BuildContext context, index) { return Card( margin: const EdgeInsets.all(15.0), color: Colors.green[600], child: ListTile( title: Text(planty[index].name ?? 'name'), ), ); } ), ); } else { return const Center(child: Text('暂无植物数据')); } } ) );
3. 修复JSON格式
删除JSON中最后一个字段末尾多余的逗号,补全所有数组、对象的闭合符号,可先通过JSON校验工具验证格式合法性。
4. 确认资源注册
检查pubspec.yaml配置,确保已正确声明assets路径:
flutter: assets: - assets/plants.json - assets/images/
注意配置的缩进格式,路径要和实际文件存放路径完全一致。
内容的提问来源于stack exchange,提问作者Jan Kenzi Masangkay
相关产品推荐
相关产品推荐

