Flutter如何从API响应的result列表中获取并展示name字段?
问题描述
我已经通过FutureBuilder成功展示了API响应中的message字段,现在想要展示响应内result列表中每个对象的name字段。以下是相关代码和API响应模型,请教如何实现name字段的展示:
API响应模型
{"message": "success","error": false,"code": 200,"result": [{"id": 1,"name": "Lab Report"},{"id": 2,"name": "News"},{"id": 3,"name": "X-ray"},{"id": 8,"name": "Blood Test"}],"status": 200}
当前展示message的代码
Column( children: [ FutureBuilder<Categories>( future: futureAlbum, builder: (context,snapshot){ if(snapshot.hasData){ return Text(snapshot.data!.message ?? ""); }else if(snapshot.hasError){ return Text("${snapshot.error}"); } return const CircularProgressIndicator(); } ) ], ),
模型类
class Categories { String? message; bool? error; int? code; List<Result>? result; int? status; Categories({this.message, this.error, this.code, this.result, this.status}); Categories.fromJson(Map<String, dynamic> json) { message = json['message']; error = json['error']; code = json['code']; if (json['result'] != null) { result = <Result>[]; json['result'].forEach((v) { result!.add(new Result.fromJson(v)); }); } status = json['status']; } Map<String, dynamic> toJson() { final Map<String, dynamic> data = new Map<String, dynamic>(); data['message'] = this.message; data['error'] = this.error; data['code'] = this.code; if (this.result != null) { data['result'] = this.result!.map((v) => v.toJson()).toList(); } data['status'] = this.status; return data; } } class Result { int? id; String? name; Result({this.id, this.name}); Result.fromJson(Map<String, dynamic> json) { id = json['id']; name = json['name']; } Map<String, dynamic> toJson() { final Map<String, dynamic> data = new Map<String, dynamic>(); data['id'] = this.id; data['name'] = this.name; return data; } }
API请求类
import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:http/http.dart' as http; import 'ModelsForCategories.dart'; class RemoteService { Future<Categories> fetchAlbum() async { final response = await http.get(Uri.parse("http://10.0.2.2:8000/api_vi/getcategories/")); if (response.statusCode == 200) { return Categories.fromJson(json.decode(response.body)); } else { throw Exception('Failed to load album'); } } }
解决方案
你只需要修改FutureBuilder的返回内容,将原本的Text替换为可遍历result列表的组件,以下是两种常用实现方式:
方案1:使用ListView.builder(适合列表项较多的场景)
这种方式会按需渲染可见列表项,性能更优:
Column( children: [ // 保留原有的message展示 Text(snapshot.data!.message ?? ""), const SizedBox(height: 16), Expanded( child: ListView.builder( itemCount: snapshot.data!.result?.length ?? 0, itemBuilder: (context, index) { final item = snapshot.data!.result![index]; return ListTile( title: Text(item.name ?? "无名称"), ); }, ), ) ], )
方案2:使用Column(适合列表项较少的场景)
这种方式实现更简洁,直接生成所有列表项:
Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(snapshot.data!.message ?? ""), const SizedBox(height: 16), // 遍历result列表生成Text组件 ...(snapshot.data!.result?.map((item) => Padding( padding: const EdgeInsets.symmetric(vertical: 4), child: Text(item.name ?? "未命名"), )).toList() ?? []), ], )
完整修改后的FutureBuilder代码示例
Column( children: [ FutureBuilder<Categories>( future: futureAlbum, builder: (context, snapshot) { if (snapshot.hasData) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 展示message字段 Text(snapshot.data!.message ?? ""), const SizedBox(height: 16), // 遍历result列表展示每个name字段 ...(snapshot.data!.result?.map((resultItem) { return Padding( padding: const EdgeInsets.symmetric(vertical: 4), child: Text(resultItem.name ?? "未命名"), ); }).toList() ?? []), ], ); } else if (snapshot.hasError) { return Text("${snapshot.error}"); } return const CircularProgressIndicator(); }, ) ], )
关键注意点
- 始终判断
snapshot.data!.result是否为空,避免空指针异常; - 根据列表项数量选择合适的组件,大量数据用
ListView.builder,少量数据用Column即可。
内容的提问来源于stack exchange,提问作者Mr.Robot
相关产品推荐
相关产品推荐

