Flutter报错:type 'Null' is not a subtype of type 'int',多JSON解析失败
问题根源
你当前的代码是为解析单个Album对象编写的,但目标接口返回的是包含employees数组的JSON结构。直接用Album.fromJson解析整个返回结果时,因为找不到userId、id、title字段,会返回Null,而Album的属性是不可为null的int类型,因此触发type 'Null' is not a subtype of type 'int'错误。
完整解决方案
1. 定义匹配接口的员工数据模型
根据接口返回的员工结构,创建Employee类:
class Employee { final int id; final String name; final String position; final String department; Employee({ required this.id, required this.name, required this.position, required this.department, }); // 从JSON解析员工对象 factory Employee.fromJson(Map<String, dynamic> json) { return Employee( id: json['id'] as int, name: json['name'] as String, position: json['position'] as String, department: json['department'] as String, ); } }
2. 修改数据获取方法
更新请求逻辑,解析接口中的employees数组:
Future<List<Employee>> fetchEmployees() async { final response = await http.get( Uri.parse('https://my-json-server.typicode.com/fluttirci/testJson/db'), ); if (response.statusCode == 200) { Map<String, dynamic> data = jsonDecode(response.body); List<dynamic> employeesList = data['employees']; return employeesList.map((json) => Employee.fromJson(json)).toList(); } else { throw Exception('加载员工数据失败'); } }
3. 用表格展示所有员工数据
替换原有UI代码,实现可横向滚动的表格:
import 'dart:async'; import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; // 插入Employee类和fetchEmployees方法 void main() => runApp(const MyApp()); class MyApp extends StatefulWidget { const MyApp({super.key}); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { late Future<List<Employee>> futureEmployees; @override void initState() { super.initState(); futureEmployees = fetchEmployees(); } @override Widget build(BuildContext context) { return MaterialApp( title: '员工数据展示', theme: ThemeData( brightness: Brightness.dark, primarySwatch: Colors.blue, ), home: Scaffold( appBar: AppBar( title: const Text('员工数据'), ), body: FutureBuilder<List<Employee>>( future: futureEmployees, builder: (context, snapshot) { if (snapshot.hasData) { return SingleChildScrollView( scrollDirection: Axis.horizontal, child: DataTable( columns: const [ DataColumn(label: Text('ID')), DataColumn(label: Text('姓名')), DataColumn(label: Text('职位')), DataColumn(label: Text('部门')), ], rows: snapshot.data!.map((employee) { return DataRow(cells: [ DataCell(Text(employee.id.toString())), DataCell(Text(employee.name)), DataCell(Text(employee.position)), DataCell(Text(employee.department)), ]); }).toList(), ), ); } else if (snapshot.hasError) { return Center(child: Text('${snapshot.error}')); } return const Center(child: CircularProgressIndicator()); }, ), ), ); } }
可选:网格布局展示
如果需要用网格卡片展示,替换FutureBuilder中的表格部分为以下代码:
return GridView.builder( padding: const EdgeInsets.all(8), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, crossAxisSpacing: 8, mainAxisSpacing: 8, ), itemCount: snapshot.data!.length, itemBuilder: (context, index) { Employee employee = snapshot.data![index]; return Card( child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('ID: ${employee.id}'), const SizedBox(height: 8), Text('姓名: ${employee.name}', style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), const SizedBox(height: 4), Text('职位: ${employee.position}'), Text('部门: ${employee.department}'), ], ), ), ); }, );
内容的提问来源于stack exchange,提问作者crag hack
相关产品推荐
相关产品推荐

