Flutter DistanceMatrix JSON 无法正确解析

Posted

技术标签:

【中文标题】Flutter DistanceMatrix JSON 无法正确解析【英文标题】:Flutter DistanceMatrix JSON won't parse correctly 【发布时间】:2020-07-24 18:41:17 【问题描述】:

我已阅读并尝试了所有帖子/视频,但没有任何效果。请帮助对代码感兴趣的网络管理员。

我不知道如何将返回的 json 对象转换为我可以使用的可用列表/字符串。我只需要元素 -> 距离 -> 文本和文本小部件的值。

返回的 JSON 对象


   "destination_addresses" : [ "The destination address" ],
   "origin_addresses" : [ "The origin address" ],
   "rows" : [
      
         "elements" : [
            
               "distance" : 
                  "text" : "7 m",
                  "value" : 7
               ,
               "duration" : 
                  "text" : "1 min.",
                  "value" : 1
               ,
               "status" : "OK"
            
         ]
      
   ],
   "status" : "OK"

代码 sn-p(删除之前的尝试):

Future<String> getLinkForCalculation() async
    var _latUser = "INSERT LATUSER";
    var _lonUser = "INSERT LONUSER";
    var _latClient = "INSERT LATCLIENT";
    var _lonClient = "INSERT LONCLIENT";
    var _key = "INSERT_API_KEY";
    var link = "https://maps.googleapis.com/maps/api/distancematrix/json?units=metric&origins=$_latUser,$_lonUser&destinations=$_latClient,$_lonClient&key=$_key";
    print(link);
    return link;
  


  Future<List> calculateDistanceFromLink()async
    var link = await getLinkForCalculation();
    Dio finalLink = new Dio();
    Response distanceData = await finalLink.get(link);

    print(distanceData.data);

  

我已阅读并尝试过:

Flutter and Distance Matrix API parsing json(实现了类,导入了 loadData() 方法,但我的应用程序到处出错) https://medium.com/flutterdevs/parsing-complex-json-in-flutter-b7f991611d3e(实现并更改了类以使用我的数据。不再工作。) Unhandled Exception: InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List<dynamic> How to Deserialize a list of objects from json in flutter Flutter: Get data from a list of json

【问题讨论】:

【参考方案1】:

将以下代码保存为MapResponse.dart,然后使用

将您的响应正文解析为该模型

final mapResponse = mapResponseFromJson(jsonString);

//
//     final mapResponse = mapResponseFromJson(jsonString);

import 'dart:convert';

class MapResponse 
    final List<String> destinationAddresses;
    final List<String> originAddresses;
    final List<Row> rows;
    final String status;

    MapResponse(
        this.destinationAddresses,
        this.originAddresses,
        this.rows,
        this.status,
    );

    factory MapResponse.fromJson(String str) => MapResponse.fromMap(json.decode(str));

    String toJson() => json.encode(toMap());

    factory MapResponse.fromMap(Map<String, dynamic> json) => MapResponse(
        destinationAddresses: json["destination_addresses"] == null ? null : List<String>.from(json["destination_addresses"].map((x) => x)),
        originAddresses: json["origin_addresses"] == null ? null : List<String>.from(json["origin_addresses"].map((x) => x)),
        rows: json["rows"] == null ? null : List<Row>.from(json["rows"].map((x) => Row.fromMap(x))),
        status: json["status"] == null ? null : json["status"],
    );

    Map<String, dynamic> toMap() => 
        "destination_addresses": destinationAddresses == null ? null : List<dynamic>.from(destinationAddresses.map((x) => x)),
        "origin_addresses": originAddresses == null ? null : List<dynamic>.from(originAddresses.map((x) => x)),
        "rows": rows == null ? null : List<dynamic>.from(rows.map((x) => x.toMap())),
        "status": status == null ? null : status,
    ;


class Row 
    final List<Location> elements;

    Row(
        this.elements,
    );

    factory Row.fromJson(String str) => Row.fromMap(json.decode(str));

    String toJson() => json.encode(toMap());

    factory Row.fromMap(Map<String, dynamic> json) => Row(
        elements: json["elements"] == null ? null : List<Location>.from(json["elements"].map((x) => Location.fromMap(x))),
    );

    Map<String, dynamic> toMap() => 
        "elements": elements == null ? null : List<dynamic>.from(elements.map((x) => x.toMap())),
    ;


class Location 
    final Distance distance;
    final Distance duration;
    final String status;

    Location(
        this.distance,
        this.duration,
        this.status,
    );

    factory Location.fromJson(String str) => Location.fromMap(json.decode(str));

    String toJson() => json.encode(toMap());

    factory Location.fromMap(Map<String, dynamic> json) => Location(
        distance: json["distance"] == null ? null : Distance.fromMap(json["distance"]),
        duration: json["duration"] == null ? null : Distance.fromMap(json["duration"]),
        status: json["status"] == null ? null : json["status"],
    );

    Map<String, dynamic> toMap() => 
        "distance": distance == null ? null : distance.toMap(),
        "duration": duration == null ? null : duration.toMap(),
        "status": status == null ? null : status,
    ;


class Distance 
    final String text;
    final int value;

    Distance(
        this.text,
        this.value,
    );

    factory Distance.fromJson(String str) => Distance.fromMap(json.decode(str));

    String toJson() => json.encode(toMap());

    factory Distance.fromMap(Map<String, dynamic> json) => Distance(
        text: json["text"] == null ? null : json["text"],
        value: json["value"] == null ? null : json["value"],
    );

    Map<String, dynamic> toMap() => 
        "text": text == null ? null : text,
        "value": value == null ? null : value,
    ;

【讨论】:

但是如何使用 FutureBuilder 中返回的值? 您可以通过调用mapresponse.destinationAddresses访问该对象内的数据【参考方案2】:

我不是 Flutter 开发人员,因此无法在 Text 小部件部分为您提供帮助。但是我已经做了这个例子来说明如何从 JSON 中获取值:

import 'dart:convert';

class Element 
  final String text;
  final int value;

  Element.fromJson(dynamic json)
      : text = json['text'] as String,
        value = json['value'] as int;

  @override
  String toString() => 'text: $text\nvalue: $value';


void main() 
  const jsonString = '''
  
   "destination_addresses" : [ "The destination address" ],
   "origin_addresses" : [ "The origin address" ],
   "rows" : [
      
         "elements" : [
            
               "distance" : 
                  "text" : "7 m",
                  "value" : 7
               ,
               "duration" : 
                  "text" : "1 min.",
                  "value" : 1
               ,
               "status" : "OK"
            
         ]
      
   ],
   "status" : "OK"

''';

  final dynamic jsonObj = json.decode(jsonString);

  final list = Element.fromJson(jsonObj['rows'][0]['elements'][0]['distance']);
  print(list);

如您所见,如果数据类型是动态的,那么浏览 JSON 以从中获取特定数据非常容易。这样做的副作用是类型安全从分析仪中消失了,因此您应该只在小的孤立区域使用动态的力量,例如。解析然后返回正常类型的安全对象并在其余代码中使用它们。

【讨论】:

以上是关于Flutter DistanceMatrix JSON 无法正确解析的主要内容,如果未能解决你的问题,请参考以下文章

R中存在哪些技术来可视化“距离矩阵”?

Flutter 和 Openlayers - 包括 Flutter 中的 js 库

在 Flutter 中使用 JS 库

基于 JS 的高性能 Flutter 动态化框架 MXFlutter

Flutter 使用 flutter_inappbrowser 加载 H5 及与 js 交互,Methods marked with @UiThread must be executed on th

Flutter-node.js 对的最佳聊天框架?