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

Flutter报错:type 'String'不是Map<String, dynamic>子类型,求解决

Flutter解析XML转JSON时type 'String' is not a subtype of type 'Map<String, dynamic>'错误解决方法

错误原因

  1. Model类型不匹配:你的Model类中,fromJson方法多处用??""作为默认值,但当目标字段需要Map<String, dynamic>或List类型时,传入空字符串会直接触发类型转换错误。比如Rss.fromJson(json["rss"]??""),若json["rss"]不存在,会传入空字符串,而Rss.fromJson要求的是Map类型。
  2. 赋值顺序错误:API调用中,counter在haberResult未赋值前就尝试获取其属性长度,不仅会导致空指针,还会影响后续UI渲染。

修正后的代码

1. 修正后的Model文件

// To parse this JSON data, do
//
//     final economylistXml = economylistXmlFromJson(jsonString);

import 'dart:convert';

EconomylistXml economylistXmlFromJson(String str) => EconomylistXml.fromJson(json.decode(str));

String economylistXmlToJson(EconomylistXml data) => json.encode(data.toJson());

class EconomylistXml {
  EconomylistXml({
    required this.rss,
  });

  Rss rss;

  factory EconomylistXml.fromJson(Map<String, dynamic> json) => EconomylistXml(
    rss: Rss.fromJson(json["rss"] ?? {}),
  );

  Map<String, dynamic>? toJson() => {
    "rss": rss.toJson(),
  };
}

class Rss {
  Rss({
    required this.empty,
    required this.channel,
  });

  Empty empty;
  Channel channel;

  factory Rss.fromJson(Map<String, dynamic> json) => Rss(
    empty: Empty.fromJson(json["\u0024"] ?? {}),
    channel: Channel.fromJson(json["channel"] ?? {}),
  );

  Map<String, dynamic>? toJson() => {
    "\u0024": empty.toJson(),
    "channel": channel.toJson(),
  };
}

class Channel {
  Channel({
    required this.title,
    required this.link,
    required this.description,
    required this.language,
    required this.copyright,
    required this.image,
    required this.item,
  });

  String? title;
  String? link;
  String? description;
  String? language;
  String? copyright;
  Image image;
  List<Item> item;

  factory Channel.fromJson(Map<String, dynamic> json) => Channel(
    title: json["title"] ?? "",
    link: json["link"] ?? "",
    description: json["description"] ?? "",
    language: json["language"] ?? "",
    copyright: json["copyright"] ?? "",
    image: Image.fromJson(json["image"] ?? {}),
    item: (json["item"] as List?)?.map((x) => Item.fromJson(x as Map<String, dynamic>)).toList() ?? [],
  );

  Map<String, dynamic>? toJson() => {
    "title": title,
    "link": link,
    "description": description,
    "language": language,
    "copyright": copyright,
    "image": image.toJson(),
    "item": List<dynamic>.from(item.map((x) => x.toJson())),
  };
}

class Image {
  Image({
    required this.title,
    required this.url,
    required this.link,
    required this.width,
    required this.height,
  });

  String? title;
  String? url;
  String? link;
  String? width;
  String? height;

  factory Image.fromJson(Map<String, dynamic> json) => Image(
    title: json["title"] ?? "",
    url: json["url"] ?? "",
    link: json["link"] ?? "",
    width: json["width"] ?? "",
    height: json["height"] ?? "",
  );

  Map<String, dynamic>? toJson() => {
    "title": title,
    "url": url,
    "link": link,
    "width": width,
    "height": height,
  };
}

class Item {
  Item({
    required this.title,
    required this.description,
    required this.link,
    required this.pubDate,
  });

  String? title;
  String? description;
  String? link;
  String? pubDate;

  factory Item.fromJson(Map<String, dynamic> json) => Item(
    title: json["title"] ?? "",
    description: json["description"] ?? "",
    link: json["link"] ?? "",
    pubDate: json["pubDate"] ?? "",
  );

  Map<String, dynamic>? toJson() => {
    "title": title,
    "description": description,
    "link": link,
    "pubDate": pubDate,
  };
}

class Empty {
  Empty({
    required this.version,
  });

  String? version;

  factory Empty.fromJson(Map<String, dynamic> json) => Empty(
    version: json["version"] ?? "",
  );

  Map<String, dynamic>? toJson() => {
    "version": version,
  };
}

2. 修正后的API调用文件

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

import '../models/apis/economy_xml.dart';
import 'haberdetail.dart';


class Economy extends StatefulWidget {
  const Economy({Key? key}) : super(key: key);

  @override
  State<Economy> createState() => _EconomyState();
}

class _EconomyState extends State<Economy> {
  ScrollController? controller;
  final scaffoldKey = GlobalKey<ScaffoldState>();
  final url = Uri.parse('https://v1.nocodeapi.com/miktadtahir/xml_to_json/htvLvoPDCwIEyTxa?url=https://ekonomigundemi.com.tr/rss/ekonomi/246.xml');
  int? counter;
  EconomylistXml? haberResult;

  Future callHaber() async {
    try{
      final response = await http.get(url);

      if(response.statusCode == 200){
        var rss = economylistXmlFromJson(response.body);

        if(mounted){
          setState(() {
            haberResult = rss;
            counter = haberResult?.rss.channel.item.length;
          });
        }
        return rss;
      } else {
        print(response.statusCode);
      }
    } catch(e) {
      print(e.toString());
    }
  }

  @override
  void initState() {
    super.initState();
    callHaber();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: false,
        automaticallyImplyLeading: false,
        title: const Text('Ekonomi Haberleri'),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: counter != null ?
          ListView.builder(
              itemCount: counter!,
              itemBuilder: (context, index){
                final item = haberResult?.rss.channel.item[index];
                return Card(
                  child: ListTile(
                    title: Text(item?.title ?? ""),
                    // 注意:description是文本内容,若要显示图片需解析其中的img标签提取链接
                    leading: CircleAvatar(
                      backgroundImage: NetworkImage(item?.description ?? ""),
                    ),
                    onTap: () => Navigator.push(
                      context, 
                      MaterialPageRoute(
                        builder: (context) => HaberDetailScreen(
                          subtitle: item?.title ?? "", 
                          title: item?.description ?? ""
                        )
                      )
                    ),
                  ),
                );
              }) : const Center(child: CircularProgressIndicator()),
        ),
      ),
    );
  }
}

关键修正点

  1. Model类型适配:
    • 需要Map类型的字段,默认值从""改为{},确保传入类型匹配
    • 列表字段改用安全转换逻辑,避免空值或非列表类型导致的错误
  2. API调用逻辑修复:
    • 调整counter赋值顺序,先给haberResult赋值再获取列表长度
    • 修复if(mounted);的语法错误,避免不必要的状态更新
    • 给counter指定明确的int?类型,消除类型歧义

内容的提问来源于stack exchange,提问作者Mıktad Tahir Durak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 05:49:11