簡體   English   中英

Flutter 從資產中讀取本地 Json

[英]Flutter read local Json from assets

我試圖了解如何在 Flutter/Dart 中使用 Json。

我想從資產文件夾中讀取本地 Json 並將其顯示在屏幕上。

我在資產文件夾中有以下 Json

{
  "title": [
    {
      "number": 8,
      "firstarray": [
        26.6, 27, 26.6, 22.9, 27.1, 26.8, 

      ],
      "secondarray": [
        26.6, 27, 26.6, 22.9, 27.1, 26.8, 
      ]
    },
    {
      "number": 9,
      "firstarray": [
        26.6, 27, 26.6, 22.9, 27.1, 26.8, 
      ],
      "secondarray": [
        26.6, 27, 26.6, 22.9, 27.1, 26.8, 
      ]
    }
  ]
}


我試圖創建一個類“DataModel”以便能夠從 JSON 文件中讀取。

class DataModel {
  DataModel({this.measure});

  List<DataTitle>? measure;

  factory DataModel.fromJson(Map<String, dynamic> json) {
    return DataModel(
      measure: List<DataTitle>.from(
          json['title'].map((c) => DataTitle.fromJson(c)).toList()),
    );
  }
}

class DataTitle {
  DataTitle(
      {required this.number,
      required this.firstarray,
      required this.secondarray});

  int? number;
  List<double>? firstarray;
  List<double>? secondarray;

  DataTitle.fromJson(Map<String, dynamic> json) {
    number = json['number'];
    firstarray = json['firstarray'] == null
        ? []
        : List<double>.from(json['firstarray'].map((x) => x.toDouble()));
    secondarray = json['secondarray'] == null
        ? []
        : List<double>.from(json['secondarray'].map((x) => x.toDouble()));
  }
}


我正在嘗試讀取並打印到控制台,如下所示。

  Future loadData() async {
    String jsonString = await _loadData();
    final jsonResponse = json.decode(jsonString);
    DataTitle measure = DataTitle.fromJson(jsonResponse);
    print('${measure.number} - ${measure.firstarray} - ${measure.secondarray}');
  }

我在控制台打印出來,

flutter: null - [] - []

但我期待

flutter:  8 -  26.6, 27, 26.6, 22.9, 27.1, 26.8 - 26.6, 27, 26.6, 22.9, 27.1, 26.8, 

修復您的模型和未來的無效:

數據模型

class DataModel {
  List<Title>? title;

  DataModel({this.title});

  DataModel.fromJson(Map<String, dynamic> json) {
    if (json['title'] != null) {
      title = <Title>[];
      json['title'].forEach((v) {
        title!.add(new Title.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    if (this.title != null) {
      data['title'] = this.title!.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class Title {
  int? number;
  List<double>? firstarray;
  List<int>? secondarray;

  Title({this.number, this.firstarray, this.secondarray});

  Title.fromJson(Map<String, dynamic> json) {
    number = json['number'];
    firstarray = json['firstarray'].cast<double>();
    secondarray = json['secondarray'].cast<int>();
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['number'] = this.number;
    data['firstarray'] = this.firstarray;
    data['secondarray'] = this.secondarray;
    return data;
  }
}

功能

Future<DataModel> readJsonData() async {
    final jsondata = await rootBundle.loadString('assets/measurelist.json');
    final list = json.decode(jsondata) as Map<String, dynamic> ;
    DataModel res = DataModel.fromJson(list);
    return res;
  }

更新部分:

您嘗試將整個 json 結構轉換為DataModel類的對象。 但是,在您的 json 中,只有title節點下的列表包含DataModel對象。

請檢查下面的loadData函數,我首先從title節點中提取列表,然后為列表中的每個元素創建一個DataModel對象。

class DataModel {
  DataModel({this.measure});

  List<DataTitle>? measure;

  factory DataModel.fromJson(Map<String, dynamic> json) {
    return DataModel(
      measure: List<DataTitle>.from(
          json['title'].map((c) => DataTitle.fromJson(c)).toList()),
    );
  }
}

class DataTitle {
  DataTitle(
      {required this.number,
      required this.firstarray,
      required this.secondarray});

  int? number;
  List<double>? firstarray;
  List<double>? secondarray;

  DataTitle.fromJson(Map<String, dynamic> json) {
    number = json['number'];
    firstarray = json['firstarray'] == null
        ? []
        : List<double>.from(json['firstarray'].map((x) => x.toDouble()));
    secondarray = json['secondarray'] == null
        ? []
        : List<double>.from(json['secondarray'].map((x) => x.toDouble()));
  }

  @override
  String toString() {
    return 'DataTitle{number: $number, firstarray: $firstarray, secondarray: $secondarray}';
  }
}

Future loadData() async {
  final jsonString = await rootBundle.loadString('assets/data.json');
  final decodedJson = json.decode(jsonString);
  List<DataTitle> dataTileList= (decodedJson ['title'] as List)
      .map((jsonElement) => DataTitle.fromJson(jsonElement))
      .toList();
  print(dataTileList.first);
  print(dataTileList.last);
}

原始答案

在您的代碼中,您的 json 數據示例與您嘗試讀取它的方式不匹配。 您提供了一個元素,但您嘗試讀取元素列表。

如果 json 數據包含單個元素

您的 json 結構屬於Map<String, dynamic>類型,因此這是json.decode返回的數據類型(或者您也使用方法jsonDecode from import 'dart:convert'; )。

然后,您嘗試將此Map轉換為List<dynamic> ,這顯然失敗了。

相反,第一部分應如下所示:

    final jsonString =
        await rootBundle.rootBundle.loadString('assets/measurelist.json');
    final json = json.decode(jsonString) as Map<String, dynamic>;

之后,您需要調用數據模型類的fromJson方法。

在您的示例中,您嘗試使用map為 json 數組中的每個元素創建一個對象。 但是,在您的示例 json 中,您只有一個不屬於數組的對象。 所以那張map沒有意義。

應該工作的是直接在您提供的單個數據元素上調用fromJson方法,例如:

   return DataModel.fromJson(json);

綜上所述,您的方法應如下所示:

  Future<DataModel> readJsonData() async {
    final jsonString =
        await rootBundle.rootBundle.loadString('assets/measurelist.json');
    final json = json.decode(jsonString) as Map<String, dynamic>;
    return DataModel.fromJson(json);
  }

如果 json 數據包含元素列表

如果您的數據模型實際上包含元素列表,則 json 數據將如下所示:

[
{
  "title": [
    {
      "number": 8,
      "firstarray": [
        26.6, 27, 26.6, 2, 27.1, 26.8, 26.6, 26.8, 26.8, 27.2, 26.9, 0, 26.8,
        26.8, 26.9, 0, 27.1, 26.8, 27.2, 26.7
      ],
      "secondarray": [
        0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 6.4, 6.4, 2.1, 2, 0, 0, 2, 0, 0, 6.3
      ]
    }
  ]
},
{
  "title": [
    {
      "number": 9,
      "firstarray": [
        26.6, 27, 26.6, 2, 27.1, 26.8, 26.6, 26.8, 26.8, 27.2, 26.9, 0, 26.8,
        26.8, 26.9, 0, 27.1, 26.8, 27.2, 26.7
      ],
      "secondarray": [
        0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 6.4, 6.4, 2.1, 2, 0, 0, 2, 0, 0, 6.3
      ]
    }
  ]
},

...

]

那么你的解析方法應該是這樣的:

  Future<List<DataModel>> readJsonData() async {
    final jsonString =
        await rootBundle.rootBundle.loadString('assets/measurelist.json');
    final listOfJsonElements = json.decode(jsonString) as List;
    return listOfJsonElements.map((jsonElement) => DataModel.fromJson(jsonElement)).toList();
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM