You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart解析含嵌套对象数组的JSON?Flutter开发实战问题

解决Flutter中解析JSON嵌套对象数组的类型不匹配问题

这个错误在Flutter解析JSON时很常见,我来帮你理清问题根源并给出解决方案:

错误原因

当你对jsonMap['genres']调用map((i) => Genre.fromJson(i))时,返回的是Iterable<dynamic>类型,直接调用.toList()会生成List<dynamic>,但你的MovieDetail类里genres字段声明的是List<Genre>——Dart是强类型语言,所以会抛出类型不匹配的错误。

解决方案

你可以通过以下几种方式明确指定转换后的列表类型:

方案1:使用List<Genre>.from()

将genres的解析代码改成这样:

genres = List<Genre>.from(jsonMap['genres'].map((i) => Genre.fromJson(i))),

List<Genre>.from()会把传入的Iterable直接转换为明确的List<Genre>类型,完美匹配你的字段类型。

方案2:使用.cast<Genre>()

也可以在map之后加上类型转换:

genres = (jsonMap['genres'].map((i) => Genre.fromJson(i))).cast<Genre>().toList(),

.cast<Genre>()会把Iterable的元素类型强制转换为Genre,再转成List。

额外的代码优化建议

我还注意到你的代码里有几个小问题,顺便帮你修正:

  1. 变量类型缺失:backgroundArtUrl没有声明类型,应该加上String
  2. 图片路径搞反:你把backdrop_path拼到了posterArtUrl,poster_path拼到了backgroundArtUrl,这和TMDB的定义不符(backdrop是背景大图,poster是海报图),建议调换过来
  3. 空值处理:如果API返回的backdrop_path或poster_path为null,直接拼接字符串会报错,建议加空判断

修正后的完整代码:

import 'dart:async';

class MovieDetail {
  final String title;
  final double rating;
  final String posterArtUrl;
  final String backgroundArtUrl; // 补充类型声明
  final List<Genre> genres;
  final String overview;
  final String tagline;
  final int id;

  const MovieDetail({
    this.title,
    this.rating,
    this.posterArtUrl,
    this.backgroundArtUrl,
    this.genres,
    this.overview,
    this.tagline,
    this.id,
  });

  MovieDetail.fromJson(Map jsonMap)
      : title = jsonMap['title'],
        rating = jsonMap['vote_average'].toDouble(),
        // 修正图片路径,并且处理null情况
        posterArtUrl = jsonMap['poster_path'] != null 
            ? "http://image.tmdb.org/t/p/w342${jsonMap['poster_path']}" 
            : null,
        backgroundArtUrl = jsonMap['backdrop_path'] != null
            ? "http://image.tmdb.org/t/p/w500${jsonMap['backdrop_path']}"
            : null,
        genres = List<Genre>.from(jsonMap['genres'].map((i) => Genre.fromJson(i))),
        overview = jsonMap['overview'],
        tagline = jsonMap['tagline'],
        id = jsonMap['id'];
}

class Genre {
  final int id;
  final String genre;

  const Genre(this.id, this.genre);

  Genre.fromJson(Map jsonMap)
      : id = jsonMap['id'],
        genre = jsonMap['name'];
}

这样修改后,不仅解决了genres的类型转换问题,还优化了图片路径的正确性和空值安全性。

内容的提问来源于stack exchange,提问作者rakeshdas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:08:48