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

Flutter API请求解析报错:Map<String,dynamic>无法转为List<dynamic>

问题解决:Map<String, dynamic> 无法转换为 List

错误原因

你的代码默认API返回照片对象数组(List),但实际后端返回的是单个照片对象(Map<String, dynamic>),因此在(jsonDecode(responseBody) as List)这一步强制类型转换时触发错误。

修正步骤及代码

1. 修改数据请求与解析逻辑

将返回类型从List<Photo>改为单个Photo,调整解析逻辑适配单对象返回:

import 'dart:convert';
import 'package:http/http.dart' as http;

Future<Photo> fetchPhotos(http.Client client) async {
  final response = await client.get(
    Uri.parse('Endpoint(hidden)'),
  );

  return parsePhoto(response.body);
}

Photo parsePhoto(String responseBody) {
  final parsed = jsonDecode(responseBody) as Map<String, dynamic>;
  return Photo.fromJson(parsed);
}

class Photo {
  final bool canLogin;
  final bool canRegister;
  final List<dynamic> activities;

  const Photo({
    required this.canLogin,
    required this.canRegister,
    required this.activities,
  });

  factory Photo.fromJson(Map<String, dynamic> json) {
    return Photo(
      canLogin: json['canLogin'] as bool,
      canRegister: json['canRegister'] as bool,
      activities: json['activities'] as List<dynamic>,
    );
  }
}

2. 调整UI部分适配单对象数据

修改FutureBuilder类型,同时调整页面展示逻辑(单个对象无需GridView):

import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';

class Test extends StatefulWidget {
  const Test({super.key, required this.title});

  final String title;
  @override
  State<Test> createState() => _TestState();
}

class _TestState extends State<Test> {
  late Future<Photo> getData;

  @override
  void initState() {
    getData = fetchPhotos(http.Client());
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('data'),
        backgroundColor: Colors.blue,
      ),
      floatingActionButton: TextButton(
          onPressed: () {
            setState(() {
              getData = fetchPhotos(http.Client());
            });
          },
          child: const Text('Reload')),
      body: FutureBuilder<Photo>(
        future: getData,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            devtools.log('has data');
            return PhotoDetail(photo: snapshot.data!);
          } else if (snapshot.hasError) {
            devtools.log('has error');
            return Text(snapshot.error.toString());
          }
          return const CircularProgressIndicator();
        },
      ),
    );
  }
}

class PhotoDetail extends StatelessWidget {
  const PhotoDetail({super.key, required this.photo});

  final Photo photo;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('可登录: ${photo.canLogin}'),
          Text('可注册: ${photo.canRegister}'),
          const SizedBox(height: 16),
          const Text('活动列表:'),
          ...photo.activities.map((activity) => Text('- $activity')).toList(),
        ],
      ),
    );
  }
}

额外说明

  • 如果API确实应该返回数组,需检查后端接口是否正确返回[]包裹的数组格式;
  • 原代码dispose方法中重新赋值getData属于无用操作,已移除;
  • 刷新按钮逻辑修改为重新发起请求,确保点击后获取最新数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 23:53:09