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

如何将JSON列表转换为Flutter的User模型类列表并用于ListView展示

解决JSON数组转User列表的GetX实现方案

问题根源

API返回的是JSON数组(List<dynamic>类型),但你直接用User.fromJson(response.body)尝试解析,相当于把数组当成了单个用户对象的Map<String, dynamic>,自然会触发类型不匹配错误。修改User.fromJson参数为列表后只能取第一个元素ID,是因为没做遍历解析,只处理了数组的第一个元素。

正确实现步骤

1. 确保模型类的fromJson职责单一

User及关联的Address、Geo、Company模型的fromJson方法只负责解析单个对象,参数保持为Map<String, dynamic>:

class User {
  final int id;
  final String name;
  final Address address;
  final Company company;

  User({
    required this.id,
    required this.name,
    required this.address,
    required this.company,
  });

  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      id: json['id'],
      name: json['name'],
      address: Address.fromJson(json['address']),
      company: Company.fromJson(json['company']),
    );
  }
}

class Address {
  final String street;
  final Geo geo;

  Address({required this.street, required this.geo});

  factory Address.fromJson(Map<String, dynamic> json) {
    return Address(
      street: json['street'],
      geo: Geo.fromJson(json['geo']),
    );
  }
}

class Geo {
  final String lat;
  final String lng;

  Geo({required this.lat, required this.lng});

  factory Geo.fromJson(Map<String, dynamic> json) {
    return Geo(
      lat: json['lat'],
      lng: json['lng'],
    );
  }
}

class Company {
  final String name;

  Company({required this.name});

  factory Company.fromJson(Map<String, dynamic> json) {
    return Company(
      name: json['name'],
    );
  }
}

2. 在GetX控制器中批量解析数组

控制器里先把响应体转成List<dynamic>,再遍历每个元素,用User.fromJson逐个解析成User对象,最终组装成List<User>:

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

class UserController extends GetxController {
  final userList = <User>[].obs;
  final isLoading = false.obs;

  Future<void> fetchUsers() async {
    try {
      isLoading(true);
      final response = await http.get(Uri.parse('你的API接口地址'));
      
      if (response.statusCode == 200) {
        // 将响应JSON转成动态列表
        final List<dynamic> rawUserList = json.decode(response.body);
        // 遍历列表,逐个解析为User对象
        userList.value = rawUserList.map((userJson) => User.fromJson(userJson)).toList();
      } else {
        print('请求失败,状态码: ${response.statusCode}');
      }
    } catch (e) {
      print('请求异常: $e');
    } finally {
      isLoading(false);
    }
  }

  @override
  void onInit() {
    super.onInit();
    // 初始化时加载数据
    fetchUsers();
  }
}

3. 在ListView中展示数据

用Obx监听userList的变化,构建列表项展示所有用户数据:

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

class UserListPage extends StatelessWidget {
  final UserController controller = Get.put(UserController());

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('用户列表')),
      body: Obx(() {
        if (controller.isLoading.value) {
          return const Center(child: CircularProgressIndicator());
        }

        return ListView.builder(
          itemCount: controller.userList.length,
          itemBuilder: (context, index) {
            final user = controller.userList[index];
            return ListTile(
              title: Text(user.name),
              subtitle: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text('ID: ${user.id}'),
                  Text('街道: ${user.address.street}'),
                  Text('公司: ${user.company.name}'),
                  Text('坐标: ${user.address.geo.lat}, ${user.address.geo.lng}'),
                ],
              ),
            );
          },
        );
      }),
    );
  }
}

关键注意点

  • 不要修改User.fromJson的参数类型为列表,保持模型类只处理单个对象,遵循单一职责原则,代码更易维护。
  • 必须用json.decode(response.body)把响应字符串转成List后再处理,不能直接用response.body(它是字符串类型)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 23:20:18