【问题标题】:Flutter - Exception: type 'int' is not a subtype of type 'double'Flutter - 例外:类型“int”不是“double”类型的子类型
【发布时间】:2021-05-16 00:22:23
【问题描述】:

我很难在后台解析 JSON。 我正在使用FoodData API

这是一个菜的示例响应:

{
"fdcId": 167782,
"description": "Abiyuch, raw",
"dataType": "SR Legacy",
"publicationDate": "2019-04-01",
"ndbNumber": "9427",
"foodNutrients": [
{
"number": "318",
"name": "Vitamin A, IU",
"amount": 100,
"unitName": "IU",
"derivationCode": "A",
"derivationDescription": "Analytical"
},
{
"number": "268",
"name": "Energy",
"amount": 290,
"unitName": "kJ",
"derivationCode": "NC",
"derivationDescription": "Calculated"
},
]

我使用 JSON 到 DART 转换器并得到了这个输出-

class FoodGen {
  int fdcId;
  String description;
  String dataType;
  String publicationDate;
  String ndbNumber;
  List<FoodNutrients> foodNutrients;

  FoodGen(
      {this.fdcId,
      this.description,
      this.dataType,
      this.publicationDate,
      this.ndbNumber,
      this.foodNutrients});

  FoodGen.fromJson(Map<String, dynamic> json) {
    fdcId = json['fdcId'];
    description = json['description'];
    dataType = json['dataType'];
    publicationDate = json['publicationDate'];
    ndbNumber = json['ndbNumber'];
    if (json['foodNutrients'] != null) {
      foodNutrients = new List<FoodNutrients>();
      json['foodNutrients'].forEach((v) {
        foodNutrients.add(new FoodNutrients.fromJson(v));
      });
    }
  }

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

class FoodNutrients {
  String number;
  String name;
  double amount;
  String unitName;
  String derivationCode;
  String derivationDescription;

  FoodNutrients(
      {this.number,
      this.name,
      this.amount,
      this.unitName,
      this.derivationCode,
      this.derivationDescription});

  FoodNutrients.fromJson(Map<String, dynamic> json) {
    number = json['number'];
    name = json['name'];
    amount = json['amount'];
    unitName = json['unitName'];
    derivationCode = json['derivationCode'];
    derivationDescription = json['derivationDescription'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['number'] = this.number;
    data['name'] = this.name;
    data['amount'] = this.amount;
    data['unitName'] = this.unitName;
    data['derivationCode'] = this.derivationCode;
    data['derivationDescription'] = this.derivationDescription;
    return data;
  }
}

这是我的全部代码-

import 'dart:async';
import 'dart:convert';

import 'package:fit_app/fitness_app_theme.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

Future<List<FoodGen>> fetchPhotos(http.Client client) async {
  final response =
      await client.get('https://api.nal.usda.gov/fdc/v1/foods/list?dataType=Foundation,SR%20Legacy&pageSize=25&api_key=h8GO51P1H4e0dfvWOmVsu75dafKwNqJk41kf0HMD');

  // Use the compute function to run parsePhotos in a separate isolate.
  return compute(parsePhotos, response.body);
}

// A function that converts a response body into a List<Photo>.
List<FoodGen> parsePhotos(String responseBody) {
  final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();

  return parsed.map<FoodGen>((json) => FoodGen.fromJson(json)).toList();
}


// To parse this JSON data, do
//
//     final welcome = welcomeFromJson(jsonString);



class FoodGen {
  int fdcId;
  String description;
  String dataType;
  String publicationDate;
  String ndbNumber;
  List<FoodNutrients> foodNutrients;

  FoodGen(
      {this.fdcId,
      this.description,
      this.dataType,
      this.publicationDate,
      this.ndbNumber,
      this.foodNutrients});

  FoodGen.fromJson(Map<String, dynamic> json) {
    fdcId = json['fdcId'];
    description = json['description'];
    dataType = json['dataType'];
    publicationDate = json['publicationDate'];
    ndbNumber = json['ndbNumber'];
    if (json['foodNutrients'] != null) {
      foodNutrients = new List<FoodNutrients>();
      json['foodNutrients'].forEach((v) {
        foodNutrients.add(new FoodNutrients.fromJson(v));
      });
    }
  }

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

class FoodNutrients {
  String number;
  String name;
  double amount;
  String unitName;
  String derivationCode;
  String derivationDescription;

  FoodNutrients(
      {this.number,
      this.name,
      this.amount,
      this.unitName,
      this.derivationCode,
      this.derivationDescription});

  FoodNutrients.fromJson(Map<String, dynamic> json) {
    number = json['number'];
    name = json['name'];
    amount = json['amount'];
    unitName = json['unitName'];
    derivationCode = json['derivationCode'];
    derivationDescription = json['derivationDescription'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['number'] = this.number;
    data['name'] = this.name;
    data['amount'] = this.amount;
    data['unitName'] = this.unitName;
    data['derivationCode'] = this.derivationCode;
    data['derivationDescription'] = this.derivationDescription;
    return data;
  }
}

class FoodPage extends StatefulWidget {
  FoodPage({Key key}) : super(key: key);

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

class _FoodPageState extends State<FoodPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: FitnessAppTheme.darkBackground,
      body: FutureBuilder<List<FoodGen>>(
        future: fetchPhotos(http.Client()),
        builder: (context, snapshot) {
          if (snapshot.hasError) print(snapshot.error);

          return snapshot.hasData
              ? PhotosList(photos: snapshot.data)
              : Center(child: CircularProgressIndicator());
        },
      ),
    );
  }
}

class PhotosList extends StatelessWidget {
  final List<FoodGen> photos;

  PhotosList({Key key, this.photos}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
      ),
      itemCount: photos.length,
      itemBuilder: (context, index) {
        Text(photos[index].description.toString());
      },
    );
  }
}

但是当使用 Flutter run 运行它时,我在控制台中收到一个错误:Flutter - Exception: type 'int' is not a subtype of type 'double'

非常感谢您的帮助! 非常感谢你们!

【问题讨论】:

  • 谢谢你,我从你的建议中学到了很多!接下来我会使用动态变量...问题已解决

标签: json string flutter integer double


【解决方案1】:

我遇到了同样的问题,你可以试试这个解析:


double parseDouble(Map<String, dynamic> json, String key, {double defaultValue = 0.0}) {
  if (json == null) return defaultValue;
  
  if (!json.containsKey(key)) return defaultValue;

  var rawValue = json[key];
  if (rawValue == null) return defaultValue;

  if (rawValue is double) return rawValue;

  if (rawValue is int) {
    return rawValue.toDouble();
  }

  if (rawValue is String) {
    return double.tryParse(rawValue) ?? defaultValue;
  }

  return defaultValue;
}

【讨论】:

    【解决方案2】:

    你需要更换
    double amount;

    num amount;

    【讨论】:

      【解决方案3】:

      替换

      double amount;
      

      dynamic amount;
      

      在您不确定该值是否采用哪种格式时,请始终使用动态。它可以是 int 或 double。

      【讨论】:

      • 谢谢! @Shriya Pandya。现在我没有错误,数据不为空,但我只是得到一个空白屏幕......
      • 返回文本(照片[索引].description.toString());使用 return 关键字。
      • 我可以通过在 Text() 中添加返回来查看描述。
      【解决方案4】:

      尝试将double amount; 更改为int amount;。 看起来你在这里收到一个整数

      amount = json['amount'];
      

      然后你尝试将此整数分配给amount,它需要一个双倍

      【讨论】:

      • 这行不通!考虑amount 有时是 100,有时是 100.25。
      • 在这种情况下,我会推荐 @Akif 的解决方案
      【解决方案5】:

      您的amount 似乎是double。但有时它来自服务器的int。因此,您也需要将这些 int 值转换为 double。试试这个:

      FoodNutrients.fromJson(Map<String, dynamic> json) {
          number = json['number'];
          name = json['name'];
          amount = json['amount'].toDouble(); // Here we converted!
          unitName = json['unitName'];
          derivationCode = json['derivationCode'];
          derivationDescription = json['derivationDescription'];
        }
      
      

      【讨论】:

      • 我测试过了,但是好像没有效果……还是报错 Exception: type 'int' is not a subtype of type 'double'
      猜你喜欢
      • 2020-08-07
      • 2020-03-18
      • 2022-11-24
      • 2022-10-13
      • 2021-08-12
      • 2020-09-29
      • 2022-01-11
      • 2020-12-25
      • 1970-01-01
      相关资源
      最近更新 更多