You need to enable JavaScript to run this app. Flutter 中如何从 TheCatAPI 返回的 JSON 数组提取数据实现猫图列表展示
优惠活动
大模型
产品
解决方案
定价
更多

Flutter 中如何从 TheCatAPI 返回的 JSON 数组提取数据实现猫图列表展示

代码核心问题定位
  • 返回类型不匹配:Cat API接口返回的是对象数组,原代码的getPics()方法定义为返回单个CatApi对象,解析时直接将整个数组传给单对象的解析逻辑,无法生成有效数据。
  • 接口地址错误:原代码请求的端点不是图片搜索的目标端点,参数格式也不符合接口要求,无法拿到正确的返回数据。
  • 冗余无效代码:原代码中保留了未使用的pixabay接口地址变量,无实际执行作用。
  • ListView配置缺失:ListView.builder没有配置itemCount属性,没有明确列表的条目总数,即使拿到数据也无法正常渲染。
  • 取值逻辑错误:原代码将解析后的数据当成Map结构,通过data['url'][index]的方式取图片地址,实际解析结果是对象列表,不存在Map结构的url键,取值必然报错。
  • Model类参数顺序错误:CatApi类的构造函数参数顺序与fromJson方法传参顺序不一致,width和height字段值被颠倒。
  • 类型不匹配错误:FutureBuilder的builder内将snapshot.data强制声明为Map类型,与实际的列表类型不符,直接触发类型转换异常。
  • 冗余全局变量:State类中声明的Map data全局变量无实际作用,还会造成变量名冲突。
修正后的可运行代码
import 'dart:convert';
import 'package:cats_app_new/constants.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class HomeScreen extends StatefulWidget {
  static const routeName = '/home-screen';

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

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: getPics(),
      builder: (context, snapshot) {
        // 异常状态展示
        if (snapshot.hasError) {
          return Center(
            child: Text(
              'Failed to get response',
              style: TextStyle(
                color: Colors.red,
                fontSize: 22.0,
              ),
            ),
          );
        }
        // 加载状态展示
        if (!snapshot.hasData) {
          return Center(
            child: CircularProgressIndicator(),
          );
        }
        // 正常数据渲染列表
        final List<CatApi> catList = snapshot.data;
        return ListView.builder(
          itemCount: catList.length,
          itemBuilder: (context, index) {
            final currentCat = catList[index];
            return Column(
              children: [
                Padding(
                  padding: EdgeInsets.all(kDefaultPadding / 4),
                ),
                Container(
                  child: InkWell(
                    onTap: () {},
                    child: Image.network(
                      currentCat.url,
                      fit: BoxFit.cover,
                    ),
                  ),
                ),
              ],
            );
          },
        );
      },
    );
  }
}

Future<List<CatApi>> getPics() async {
  final requestUri = Uri.parse(
    'https://api.thecatapi.com/v1/images/search?api_key=$kApiKey'
  );
  final response = await http.get(requestUri);
  if (response.statusCode != 200) {
    throw Exception('网络请求失败,状态码:${response.statusCode}');
  }
  final List responseList = jsonDecode(response.body);
  return responseList.map(
    (itemJson) => CatApi.fromJson(itemJson)
  ).toList();
}

class CatApi {
  String id;
  String url;
  int width;
  int height;

  CatApi({
    required this.id,
    required this.url,
    required this.width,
    required this.height,
  });

  factory CatApi.fromJson(Map<String, dynamic> json) {
    return CatApi(
      id: json['id'] as String,
      url: json['url'] as String,
      width: json['width'] as int,
      height: json['height'] as int,
    );
  }

  @override
  String toString() {
    return '{${this.url}}';
  }
}
关键优化说明
  • 解析逻辑完全匹配接口返回的数组结构,遍历数组中每个元素生成对应的CatApi对象,返回列表类型给FutureBuilder。
  • ListView.builder补充了itemCount配置,明确列表渲染的条目数量,避免组件渲染异常。
  • 图片取值直接从对应列表索引的CatApi对象中读取,不再使用Map结构的错误取值逻辑。
  • 网络请求环节补充了状态码判断,遇到非200响应时抛出明确异常,避免将错误页面内容当成JSON解析引发崩溃。
  • CatApi类改用命名参数构造,避免传参顺序颠倒导致的字段值错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.31 06:06:03