如何将 JSON 资产加载到 Flutter 应用程序中?

Posted

技术标签:

【中文标题】如何将 JSON 资产加载到 Flutter 应用程序中?【英文标题】:How to load JSON assets into a Flutter App? 【发布时间】:2018-09-20 07:52:48 【问题描述】:

如何将 JSON 资源加载到我的 Flutter 应用中?

我的pubspec.yaml 文件包含以下内容:

assets:
    - assets/data.json

我一直在尝试加载数据时遇到问题。我试过了:

final json = JSON.decode(
    DefaultAssetBundle.of(context).loadString("assets/data.json")
);

但我得到了错误:

参数类型“Future”不能分配给参数类型“String”。

【问题讨论】:

显然 JSON.Decode 返回的是地图,而不是字符串 是的,我想要的最终结果是来自JSON.decodemap。我只是无法将 JSON 文件的字符串表示形式提供给它。 【参考方案1】:

@Alexandre Beaudet 的answer 是正确的,但没有提供很多关于正在发生的事情的背景信息。

当您调用loadString 时,它实际上是一个异步方法调用。您可以判断,因为它返回 Future<value> 而不仅仅是 value。这意味着它不会立即得到 String 的结果,但会在将来的某个时间点。

在 Dart 中有两种主要的异步处理方式;第一个是使用asyncawait,第二个是直接使用期货。请参阅dart guide on Asynchronous Programming。

如果你直接使用future.then,你可以从一个普通的函数(即从 initState 等)中完成它。您只需指定回调并在回调中指定如何处理结果。

void printDailyNewsDigest() 
  final future = gatherNewsReports();
  future.then((news) => print(news));

如果你想使用await,如@Alexandre 所示,你需要将你正在使用的函数标记为async,即:

Future<Void> printDailyNewsDigest() async 
  String news = await gatherNewsReports();
  print(news);

如果你重写了一个函数(即 initState),你还需要确保你没有改变返回值。这应该被 dart 2 的打字捕捉到,但 void -> Future 似乎不是。

最后要注意的一件事 - 如果您使用数据的结果来构建小部件,您可能希望使用FutureBuilder。

【讨论】:

昨天很着急,感谢您提供一些解释和上下文!【参考方案2】:

试试看:

String data = await DefaultAssetBundle.of(context).loadString("assets/data.json");
final jsonResult = jsonDecode(data); //latest Dart

【讨论】:

我也喜欢json_serializable的做法。根本不需要将该 json 作为资产包含在 pubspec.yaml 中。【参考方案3】:

您可以使用此代码:)

loadJson() async 
  String data = await rootBundle.loadString('assets/json/keyboard.json');
  jsonResult = json.decode(data);
  print(jsonResult);

可以在启动时加载:)

  @override
  void initState() 
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) async 
      await loadJson();
    );
  

需要在资产上添加 JSON

flutter:
  uses-material-design: true
  assets:
    - assets/json/keyboard.json

【讨论】:

【参考方案4】:

我使用以下内容来解析资产中的 json:

import 'dart:convert';
import 'package:flutter/services.dart' show rootBundle;
//...
Future<Map<String, dynamic>> parseJsonFromAssets(String assetsPath) async 
    print('--- Parse json from: $assetsPath');
    return rootBundle.loadString(assetsPath)
        .then((jsonStr) => jsonDecode(jsonStr));
  

使用异步:

parseJsonFromAssets(path)
    .then((dmap) => 
    // here you get json `dmap` as Map<String, dynamic>
    print(dmap);
));

使用同步:

Map<String, dynamic> dmap = await parseJsonFromAssets('assets/test.json');

【讨论】:

亲爱的雷霆 为什么 String jsonString = await _loadAStudentAsset();最终 jsonResponse = json.decode(jsonString); return chiese.fromJson(jsonResponse[0]);只给我第一行 json ..我无法检索所有行?? @DanieleAngelini 您的 Json 字符串是否包含 \n 或类似的东西?你在哪里得到第一行? jsonResponsejsonResponse[0] ? 亲爱的thundertrick可以看这里flutterforum.co/t/cannot-read-entire-file-to-parse-json/778我发布了我所有的代码...谢谢...我卡住了!!! @DanieleAngelini 看来您正在解析一个 json 数组,这可能不受支持。尝试将数组添加到json中,例如"data":[,]

以上是关于如何将 JSON 资产加载到 Flutter 应用程序中?的主要内容,如果未能解决你的问题,请参考以下文章

Flutter web:如何将资产重定向到其他域?

将 Flutter 应用迁移到 Flutter Web 时如何显示图像资产?

如何将资产文件夹中的 JSON 数据加载到 Recyclerview

如何根据其他下拉选择将本地 Json 加载到 Flutter DropDown?

如何使用android studio在flutter上加载图像

如何获得一个数组/列表,其中填充了我在 Flutter 中作为资产加载的所有图像路径?