Obecnie buduję aplikację flutter, w której chcę obliczyć odległość między niektórymi obiektami i używam do tego interfejsu API Google Distance Matrix. Mam problem z analizowaniem json przy użyciu Dart. Wszystko, czego ostatecznie chcę, to lista odległości od wyników json, abym mógł je zindeksować i zastosować do danych w mojej aplikacji.

Wyniki json wyglądają tak:

{
   "destination_addresses" : [
      "destination address",
      "destination address"
   ],
   "origin_addresses" : [ "Origin addresses here" ],
   "rows" : [
      {
         "elements" : [
            {
               "distance" : {
                  "text" : "4.3 mi",
                  "value" : 6998
               },
               "duration" : {
                  "text" : "14 mins",
                  "value" : 848
               },
               "status" : "OK"
            },
            {
               "distance" : {
                  "text" : "6.7 mi",
                  "value" : 10728
               },
               "duration" : {
                  "text" : "22 mins",
                  "value" : 1327
               },
               "status" : "OK"
            }
         ]
      }
   ],
   "status" : "OK"
}

Ostatecznie chciałbym otrzymać listę (w rzutce), która jest tylko listą wartości „tekstu” odległości w tablicy elementów, ale mam problem z odzyskaniem tego. Próbowałem utworzyć klasę i mapować do niej wyniki json, ale bez powodzenia, ponieważ nie jestem zbyt dobry w przetwarzaniu json, więc wszelkie porady dotyczące tego, jak skończyć z tą listą, byłyby wdzięczne!

Próbowałem tego kodu, aby przeanalizować json, ale naprawdę staram się, aby działał, a następnie go zastosować:

class Topleveladd {
  final String elements;

  Topleveladd({this.elements});

  factory Topleveladd.fromJson(Map<String, dynamic> parsedJson) {
    return Topleveladd(elements: parsedJson['rows']);
  }
}

class Elements {
  List<Distance> distanceslist;

  Elements({this.distanceslist});

  factory Elements.fromJson(Map<String, dynamic> parsedJson) {
    var list = parsedJson['elements'] as List;
    print(list.runtimeType); //returns List<dynamic>
    List<Distance> distancesList =
        list.map((i) => Distance.fromJson(i)).toList();
    return Elements(distanceslist: distancesList);
  }
}

class Distance {
  String text;
  Distance({this.text});

  factory Distance.fromJson(Map<String, dynamic> parsedJson) {
    return new Distance(
      text: parsedJson['distance'],
    );
  }
}
2
Duncan Roberts 26 listopad 2018, 19:12
1
Polecam ten artykuł, w którym do analizowania złożonego JSON w Flutter.
 – 
SnakeyHips
26 listopad 2018, 19:27
To jest dokładnie ten artykuł, którego używałem, aby spróbować rozwiązać ten problem, ale mam problemy, mój kod został dodany powyżej. Dziękuję Ci!
 – 
Duncan Roberts
26 listopad 2018, 19:37
1
Tak, nawet z artykułem może to być trudne. Jutro spróbuję :)
 – 
SnakeyHips
26 listopad 2018, 23:07
Dziękuję bardzo, byłaby to niesamowita pomoc!
 – 
Duncan Roberts
26 listopad 2018, 23:49

1 odpowiedź

Najlepsza odpowiedź

OK, to działa ze mną, uzyskując dostęp do JSON, który podałeś jako zasób, więc prawdopodobnie będziesz musiał zmienić metodę loadData, aby pasowała do Twoich potrzeb.

Klasa DistanceMatrix:

import 'dart:convert';
import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;

class DistanceMatrix {
  final List<String> destinations;
  final List<String> origins;
  final List<Element> elements;
  final String status;

  DistanceMatrix({this.destinations, this.origins, this.elements, this.status});

  factory DistanceMatrix.fromJson(Map<String, dynamic> json) {
    var destinationsJson = json['destination_addresses'];
    var originsJson = json['origin_addresses'];
    var rowsJson = json['rows'][0]['elements'] as List;

    return DistanceMatrix(
        destinations: destinationsJson.cast<String>(),
        origins: originsJson.cast<String>(),
        elements: rowsJson.map((i) => new Element.fromJson(i)).toList(),
        status: json['status']);
  }

  static Future<DistanceMatrix> loadData() async {
    DistanceMatrix distanceMatrix;
    try{
          String jsonData = await rootBundle.loadString('assets/data.json');
    distanceMatrix = new DistanceMatrix.fromJson(json.decode(jsonData));
    } catch (e){
      print(e);
    }
    return distanceMatrix;
  }
}

class Element {
  final Distance distance;
  final Duration duration;
  final String status;

  Element({this.distance, this.duration, this.status});

  factory Element.fromJson(Map<String, dynamic> json) {
    return Element(
        distance: new Distance.fromJson(json['distance']),
        duration: new Duration.fromJson(json['duration']),
        status: json['status']);
  }
}

class Distance {
  final String text;
  final int value;

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

  factory Distance.fromJson(Map<String, dynamic> json) {
    return new Distance(text: json['text'], value: json['value']);
  }
}

class Duration {
  final String text;
  final int value;

  Duration({this.text, this.value});

  factory Duration.fromJson(Map<String, dynamic> json) {
    return new Duration(text: json['text'], value: json['value']);
  }
}

Main.dart, który używa ListView.builder do wyświetlania tekstu i wartości odległości jako ListTile:

import 'package:flutter/material.dart';
import 'package:hello_world/distance_matrix.dart';

void main() async {
  runApp(new MyApp(
    distanceMatrix: await DistanceMatrix.loadData(),
  ));
}

class MyApp extends StatefulWidget {
  final DistanceMatrix distanceMatrix;

  @override
  _MyAppState createState() => new _MyAppState();

  MyApp({this.distanceMatrix});
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
            appBar: AppBar(
              title: Text("Home"),
            ),
            body: Material(
                child: ListView.builder(
                itemCount: widget.distanceMatrix.elements.length,
                itemBuilder: (context, index){
                  return ListTile(
                    title: Text(widget.distanceMatrix.elements[index].distance.text),
                    subtitle: Text(widget.distanceMatrix.elements[index].distance.value.toString()),
                  );
                },
              )
            )));
  }
}

Obraz pokazujący, co powinieneś otrzymać:

enter image description here

8
SnakeyHips 27 listopad 2018, 12:45
Jesteś bohaterem i jestem ogromnie wdzięczny!
 – 
Duncan Roberts
27 listopad 2018, 14:14
Nie ma problemu! Jeśli możesz zaakceptować moją odpowiedź i zagłosować na nią, będzie świetnie :)
 – 
SnakeyHips
27 listopad 2018, 14:16