【问题标题】:How to load JSON assets into a Flutter App?如何将 JSON 资产加载到 Flutter 应用程序中?
【发布时间】: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 文件的字符串表示形式提供给它。

标签: dart flutter


【解决方案1】:

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

当您调用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":[{},{}]}
    猜你喜欢
    • 2015-08-29
    • 1970-01-01
    • 2019-06-17
    • 1970-01-01
    • 2023-03-21
    • 2013-03-14
    • 1970-01-01
    • 2020-09-03
    • 2017-05-23
    相关资源
    最近更新 更多