繁体   English   中英

未处理的异常类型'String'不是'index'的'int'类型的子类型

[英]Unhandeled exception Type 'String' is not a subtype of type 'int' of 'index'

我的代码中出现未处理的异常,并且我的应用程序无法正常工作。

这是我可以在日志中找到的唯一一个错误:

ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: type 'String' is not a subtype of type 'int' of 'index'

E/flutter (30126): #0 AssistantMethods.obtainPlaceDirectionDetails (package:driverapp/Assistant/assistantMethods.dart:63:41)

E/flutter (30126): <asynchronous suspension>

E/flutter (30126): #1 _NewRideScreenState.getPlaceDirection (package:driverapp/AllScreens/newRideScreen.dart:189:19)

E/flutter (30126): <asynchronous suspension>

E/flutter (30126): #2 _NewRideScreenState.build.<anonymous closure> (package:driverapp/AllScreens/newRideScreen.dart:70:15)

E/flutter (30126): <asynchronous suspension>

E/flutter (30126):

这是我的assistantMethod.dart文件代码:

static Future<DirectionDetails> obtainPlaceDirectionDetails(LatLng initialPosition, LatLng finalPosition)async

{

String directionUrl = "https://maps.googleapis.com/maps/api/directions/json?origin=${initialPosition.latitude},${initialPosition.longitude}&destination=${finalPosition.latitude},${finalPosition.longitude}&key=$mapKey";

var res = await RequestAssistant.getRequest(directionUrl);

if(res == "failed")

{

return null;

}

DirectionDetails directionDetails = DirectionDetails();

#1 错误点在这一行

directionDetails.encodedPoints = res["routes"][0]["overview_polyline"]["points"];

directionDetails.distanceText = res["routes"][0]["legs"][0]["distance"]["text"];

directionDetails.distanceValue = res["routes"][0]["legs"][0]["distance"]["value"];

directionDetails.durationText = res["routes"][0]["legs"][0]["duration"]["text"];

directionDetails.durationValue = res["routes"][0]["legs"][0]["duration"]["value"];

return directionDetails;

}

#2 错误指出这一行

var details = await AssistantMethods.obtainPlaceDirectionDetails(pickUpLatLng, dropOffLatLng);

#3 错误指出这一行

await getPlaceDirection(currentLatLng, pickUpLatLng);

请帮助我正确地做到这一点。

我认为这可能会导致您的错误:

directionDetails.encodedPoints = res["routes"][0]["overview_polyline"]["points"]; .

请发布res json 来看看它。我认为在points之前会有一个index

似乎您有一个 List 并且您在列表上放置了一个 KEY 而不是 int (索引),请检查您的 api 响应。

我检查了你的代码,它可以工作。 我的脚步

0) 在浏览器中获取 JSON

为了获取数据,我们使用 URL(来自 Google 示例的点):

https://maps.googleapis.com/maps/api/directions/json
?origin=Disneyland
&destination=Universal+Studios+Hollywood
&key=<YOUR_KEY_HERE>

响应具有这样的结构: 在此处输入图像描述

1) 以String形式获取响应

我使用http库。

Future<String> fetchData() async {
  String url = "https://maps.googleapis.com/maps/api/directions/json"
      "?origin=Disneyland"
      "&destination=Universal+Studios+Hollywood"
      "&key=<YOUR_KEY_HERE>";

  var client = http.Client();
  var response = await client.get(Uri.parse(url));

  String body = response.body;

  return body;
}

2) 解析接收到的数据

接收到的数据只是String 根据文档,我们知道这是 JSON 格式。 所以让我们解码:

String body = await fetchData();
var res = json.decode(body);

3) 找到必要的字段

当您拥有 JSON 时,您可以对其进行迭代并获取必要的数据,例如:

var distanceText = res["routes"][0]["legs"][0]["distance"]["text"];
var distanceValue = res["routes"][0]["legs"][0]["distance"]["value"];
var durationText = res["routes"][0]["legs"][0]["duration"]["text"];
var durationValue = res["routes"][0]["legs"][0]["duration"]["value"];
var encodedPoints = res["routes"][0]["overview_polyline"]["points"];

它有效:)

我的想法如何让它变得更好

1) 在 Flutter 中获取 JSON

我使用http库。

获取数据并以字符串形式返回响应:

Future<String> fetchData() async {
  String url = "https://maps.googleapis.com/maps/api/directions/json"
      "?origin=Disneyland"
      "&destination=Universal+Studios+Hollywood"
      "&key=<YOUR_KEY_HERE>";

  var response = await Requests.get(url);

  String body = response.content();

  return body;
}

2)将接收到的数据转换为模型(类)

最简单的方法是使用quicktype.io

为许多编程语言生成漂亮的类型和 JSON (de)serializers。 它可以从 JSON 推断类型,但也可以从 JSON Schema、TypeScript 和 Z57DFZ.603D2ADE4564471

你要做的是:

将 JSON 粘贴到左侧,代码出现在右侧。

因此,您将收到课程,例如:

class DirectionDetails {
  DirectionDetails({
    this.geocodedWaypoints,
    this.routes,
    this.status,
  });

  final List<GeocodedWaypoint> geocodedWaypoints;
  final List<Route> routes;
  final String status;

  factory DirectionDetails.fromJson(Map<String, dynamic> json) => DirectionDetails(
        geocodedWaypoints: json["geocoded_waypoints"] == null
            ? null
            : List<GeocodedWaypoint>.from(json["geocoded_waypoints"].map((x) => GeocodedWaypoint.fromJson(x))),
        routes: json["routes"] == null ? null : List<Route>.from(json["routes"].map((x) => Route.fromJson(x))),
        status: json["status"] == null ? null : json["status"],
      );

  Map<String, dynamic> toJson() => {
        "geocoded_waypoints":
            geocodedWaypoints == null ? null : List<dynamic>.from(geocodedWaypoints.map((x) => x.toJson())),
        "routes": routes == null ? null : List<dynamic>.from(routes.map((x) => x.toJson())),
        "status": status == null ? null : status,
      };
}

您还将收到允许您直接与 json 字符串相互转换的方法:

DirectionDetails directionDetailsFromJson(String str) => DirectionDetails.fromJson(json.decode(str));

String directionDetailsToJson(DirectionDetails data) => json.encode(data.toJson());

因此,在您的情况下,您必须使用directionDetailsFromJson来接收 Flutter 数据结构。

3) 找到必要的字段

当您拥有完整的数据结构时,您可以找到所需的所有数据,因此:

List<Widget> parseData(DirectionDetails directionDetails) {
  PolylinePoints polylinePoints = PolylinePoints();

  return directionDetails.routes.map((route) {
    var points = route.overviewPolyline.points;

    List<PointLatLng> decodedPoints = polylinePoints.decodePolyline(points);

    var distanceText = route.legs.map((leg) => leg.distance.text).join();
    var distanceValue = route.legs.map((leg) => leg.distance.value).join();

    var durationText = route.legs.map((leg) => leg.duration.text).join();
    var durationValue = route.legs.map((leg) => leg.duration.value).join();

    var stringPoints =  decodedPoints.join("\n");

    return Text(
      "distanceText: $distanceText\n\n"
      "distanceValue: $distanceValue\n\n"
      "durationText: $durationText\n\n"
      "durationValue: $durationValue\n\n"
      "points:\n$stringPoints",
    );
  }).toList();
}

为了解码 PolylinePoints,我使用了 flutter_polyline_points库。

4) 结果

在此处输入图像描述

5) 完整代码

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<Widget> items = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Container(
        padding: EdgeInsets.all(20),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            ElevatedButton(
              child: Text("Fetch Data"),
              onPressed: download,
            ),
            Expanded(
              child: ListView.separated(
                shrinkWrap: true,
                itemBuilder: (BuildContext context, int index) => items[index],
                separatorBuilder: (BuildContext context, int index) => Container(
                  height: 1,
                  color: Colors.grey,
                ),
                itemCount: items.length,
              ),
            )
          ],
        ),
      ),
    );
  }

  void download() async {
    String body = await fetchData();
    DirectionDetails directionDetails = directionDetailsFromJson(body);
    var routes = parseData(directionDetails);

    setState(() {
      items = routes;
    });
  }

  Future<String> fetchData() async {
    String url = "https://maps.googleapis.com/maps/api/directions/json"
        "?origin=Disneyland"
        "&destination=Universal+Studios+Hollywood"
        "&key=<YOUR_KEY_HERE>";

    var client = http.Client();
    var response = await client.get(Uri.parse(url));

    String body = response.body;

    return body;
  }

  List<Widget> parseData(DirectionDetails directionDetails) {
    PolylinePoints polylinePoints = PolylinePoints();

    return directionDetails.routes.map((route) {
      var points = route.overviewPolyline.points;

      List<PointLatLng> decodedPoints = polylinePoints.decodePolyline(points);

      var distanceText = route.legs.map((leg) => leg.distance.text).join();
      var distanceValue = route.legs.map((leg) => leg.distance.value).join();

      var durationText = route.legs.map((leg) => leg.duration.text).join();
      var durationValue = route.legs.map((leg) => leg.duration.value).join();

      var stringPoints = decodedPoints.join("\n");

      return Text(
        "distanceText: $distanceText\n\n"
        "distanceValue: $distanceValue\n\n"
        "durationText: $durationText\n\n"
        "durationValue: $durationValue\n\n"
        "points:\n$stringPoints",
      );
    }).toList();
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM