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

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();
      },
    )
  ],
)

关键注意点

  1. 始终判断snapshot.data!.result是否为空,避免空指针异常;
  2. 根据列表项数量选择合适的组件,大量数据用ListView.builder,少量数据用Column即可。

内容的提问来源于stack exchange,提问作者Mr.Robot

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 05:50:37