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

Flutter求助:Future<ArticleModel?>无法赋值给Future<List>?类型不匹配问题

解决FutureBuilder类型不匹配错误:Future<ArticleModel?>无法赋值给Future<List>?

问题根源

你的代码存在两个核心不匹配:

  1. ApiNewsPage.getNewsArticles() 返回的是单个ArticleModel?的Future,但FutureBuilder<List>要求传入返回列表类型的Future,直接导致类型报错。
  2. 从接口解析逻辑来看,你当前的ArticleModel.fromJson是按单个文章对象解析的,但实际API应该返回的是文章数组(否则搜索功能也没有意义),所以解析逻辑也需要调整。

分步修复代码

1. 修改API服务,返回文章列表

调整ApiNewsPage的getNewsArticles方法,让它返回List<ArticleModel>类型的Future,同时适配JSON数组的解析:

class ApiNewsPage {
  final String url = newsJsonLink; // Link news
  Future<List<ArticleModel>> getNewsArticles() async {
    String nameDB = "articledata.json";
    var dir = await getTemporaryDirectory();

    File file = File(dir.path + "/" + nameDB);
    if(file.existsSync()) {
      print("Loading Articles from cache");
      var jsonData = file.readAsStringSync();
      // 解析JSON数组为文章列表
      List<dynamic> jsonList = json.decode(jsonData);
      return jsonList.map((json) => ArticleModel.fromJson(json)).toList();
    } else {
      print("Fetching articles from API internet");
      var response = await http.get(Uri.parse(url));
      if (response.statusCode == 200) {
        var jsonArticle = response.body;
        List<dynamic> jsonList = json.decode(jsonArticle);
        List<ArticleModel> res = jsonList.map((json) => ArticleModel.fromJson(json)).toList();
        /// save json in local file
        file.writeAsStringSync(jsonArticle, flush: true, mode: FileMode.write);
        return res;
      } else {
        // 请求失败时返回空列表(可根据需求改为抛出异常)
        return [];
      }
    }
  }
}

2. 修正FutureBuilder的泛型类型

将FutureBuilder<List>明确为FutureBuilder<List<ArticleModel>>,同时优化状态判断逻辑:

actions: <Widget>[
  /// First search icon
  FutureBuilder<List<ArticleModel>>(
    future: categoryNews.getNewsArticles(),
    builder: (context, snapshot) {
      // 处理加载中、无数据的情况
      if (snapshot.connectionState != ConnectionState.done || !snapshot.hasData || snapshot.data!.isEmpty) {
        return IconButton(
          icon: const Icon(Icons.search, color: Colors.white,),
          onPressed: () {
            Navigator.of(context).push(MaterialPageRoute(
              builder: (context)=> SearchBar(posts: _posts,)
            ));
          },
        );
      }
      return IconButton(
        icon: const Icon(
          Icons.search,
          color: Colors.white,
        ),
        onPressed: () {
          Navigator.of(context).push(
            MaterialPageRoute(
              builder: (context) => SearchBar(
                posts: snapshot.data!,
              ),
            ),
          );
        },
      );
    },
  ),
],

3. 增强ArticleModel的空安全解析

为避免接口字段缺失导致的解析崩溃,给fromJson方法添加空安全判断:

factory ArticleModel.fromJson(Map<String, dynamic> parsedJson) => ArticleModel(
  id: parsedJson["id"] ?? 0,
  urlImage: parsedJson["_embedded"]?["wp:featuredmedia"]?[0]?["link"],
  urlImageSource: parsedJson["_embedded"]?['wp:featuredmedia']?[0]?["media_details"]?["sizes"]?["thumbnail"]?["source_url"],
  title: parsedJson["title"]?["rendered"]?.replaceAll("&#8217;", "'").replaceAll("<p>", "").replaceAll("</p>", "") ?? "",
  description: parsedJson['content']?['rendered'],
);

关键说明

  • 核心修复点是对齐返回类型:让API服务返回列表类型,匹配FutureBuilder的泛型要求。
  • 明确泛型类型(List<ArticleModel>)可以减少类型歧义,避免隐式转换错误。
  • 空安全处理能提升代码健壮性,防止接口字段缺失导致的崩溃。

内容的提问来源于stack exchange,提问作者Pimpi Rimpà

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 00:05:21