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

Flutter中如何在其他类的Text Widget显示API响应数据?

问题描述

已通过POST方法成功向服务器发送数据,服务器返回的响应可在控制台查看,现在需要将这些响应数据在另一个类的Text Widget中展示。


API服务类

class APIService {
  Future<DoctorResponseLoginModels> register(
      DoctorRequestLoginModels doctorLoginRequestModels) async {


    String url = "http://202.51.75.142:9028/api/PatientMaster/PostPatientLogin";

    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    var globalToken = sharedPreferences.getString("token");
    print("$globalToken");

    http.Response response = await http.post(Uri.parse(url),
        headers: {
          "Content-Type": "application/json",
          'Accept': 'application/json',
          'Authorization': 'Bearer $globalToken',
        },
        body: jsonEncode(doctorLoginRequestModels));

    var responseJson = json.decode(response.body.toString());
    DoctorResponseLoginModels responseModel =
        DoctorResponseLoginModels.fromJson(responseJson);

    print("This is ${response.body}");

    if (response.statusCode == 200) {
      sharedPreferences.setInt('code', response.statusCode);
      var StatusCode = sharedPreferences.getInt('code');
      print("This contains : $StatusCode");
      print(response.statusCode);


      return DoctorResponseLoginModels.fromJson(jsonDecode(response.body));
    } else {
      throw Exception('Failed');
    }
  }
}

请求模型类

DoctorRequestLoginModels doctorRequestLoginModelsFromJson(String str) =>
    DoctorRequestLoginModels.fromJson(json.decode(str));

String doctorRequestLoginModelsToJson(DoctorRequestLoginModels data) =>
    json.encode(data.toJson());

class DoctorRequestLoginModels {
  DoctorRequestLoginModels({
    required this.code,
    required this.username,
    required this.password,
  });

  String code;
  String username;
  String password;

  factory DoctorRequestLoginModels.fromJson(Map<String, dynamic> json) =>
      DoctorRequestLoginModels(
        code: json["code"],
        username: json["username"],
        password: json["password"],
      );

  Map<String, dynamic> toJson() => {
        "code": code,
        "username": username,
        "password": password,
      };
}

响应模型类

DoctorResponseLoginModels doctorResponseLoginModelsFromJson(String str) =>
    DoctorResponseLoginModels.fromJson(json.decode(str));

String doctorResponseLoginModelsToJson(DoctorResponseLoginModels data) =>
    json.encode(data.toJson());

class DoctorResponseLoginModels {
  DoctorResponseLoginModels({
    this.doctorId,
    this.nmCno,
    this.doctorName,
    this.contactNo,
    this.username,
    this.emailId,
    this.strEmail,
    this.id,
    this.intMobile,
    this.gender,
    this.currentAddress,
    this.depId,
    this.entryDate,
    this.password,
    this.code,
    this.isActive,
    this.hospitalName,
    this.department,
    this.deviceId,
    this.profile,
    this.token,
    this.role,
  });

  int? doctorId;
  String? nmCno;
  String? doctorName;
  String? contactNo;
  dynamic? username;
  String? emailId;
  String? strEmail;
  int? id;
  String? intMobile;
  dynamic? gender;
  String? currentAddress;
  int? depId;
  String? entryDate;
  dynamic? password;
  dynamic? code;
  bool? isActive;
  dynamic? hospitalName;
  dynamic? department;
  dynamic? deviceId;
  String? profile;
  String? token;
  String? role;

  factory DoctorResponseLoginModels.fromJson(Map<String, dynamic> json) =>
      DoctorResponseLoginModels(
        doctorId: json["doctorID"],
        nmCno: json["nmCno"],
        doctorName: json["doctorName"],
        contactNo: json["contactNo"],
        username: json["username"],
        emailId: json["emailID"],
        strEmail: json["strEmail"],
        id: json["id"],
        intMobile: json["intMobile"],
        gender: json["gender"],
        currentAddress: json["currentAddress"],
        depId: json["depId"],
        entryDate: json["entryDate"],
        password: json["password"],
        code: json["code"],
        isActive: json["isActive"],
        hospitalName: json["hospitalName"],
        department: json["department"],
        deviceId: json["deviceId"],
        profile: json["profile"],
        token: json["token"],
        role: json["role"],
      );

  Map<String, dynamic> toJson() => {
        "doctorID": doctorId,
        "nmCno": nmCno,
        "doctorName": doctorName,
        "contactNo": contactNo,
        "username": username,
        "emailID": emailId,
        "strEmail": strEmail,
        "id": id,
        "intMobile": intMobile,
        "gender": gender,
        "currentAddress": currentAddress,
        "depId": depId,
        "entryDate": entryDate,
        "password": password,
        "code": code,
        "isActive": isActive,
        "hospitalName": hospitalName,
        "department": department,
        "deviceId": deviceId,
        "profile": profile,
        "token": token,
        "role": role,
      };
}

尝试的FutureBuilder展示代码

return Scaffold(
        backgroundColor: const Color.fromRGBO(249, 249, 249, 10),
        body: Column(
          children: [
            Expanded(
                child: Container(
              height: 150.0,
              width: 150.0,
              color: Colors.grey.shade100,
              child: FutureBuilder<DoctorResponseLoginModels>(
                future: APIService().register(DoctorRequestLoginModels(
                    code: "code", username: "username", password: "password")),
                builder: (context, snapshot) {
                  switch (snapshot.connectionState) {
                    case ConnectionState.waiting:
                      return Text('Loading....');
                    default:
                      if (snapshot.hasError) {
                        return Text('Error: ${snapshot.error}');
                      } else {
                        DoctorResponseLoginModels data = snapshot.data!;

                        return Column(
                          children: [
                            Text(data.doctorName!),
                          ],
                        );
                      }
                  }
                },
              ),
            )),
          ],
        ));

控制台返回的响应数据

{"doctorID":1,"nmCno":"001","doctorName":"Dr. John Doe","contactNo":"1234567890","username":"john","emailID":"john@example.com","strEmail":"john@example.com","id":1,"intMobile":"1234567890","gender":"Male","currentAddress":"123 Street","depId":1,"entryDate":"2024-01-01","password":null,"code":null,"isActive":true,"hospitalName":"City Hospital","department":"Cardiology","deviceId":null,"profile":"profile.jpg","token":"abc123","role":"Doctor"}

解决方案

1. 修复FutureBuilder重复请求问题

当前代码直接在FutureBuilder的future参数中调用API方法,会导致Widget重建时重复发起请求。建议在initState中提前初始化Future:

class DoctorInfoPage extends StatefulWidget {
  const DoctorInfoPage({super.key});

  @override
  State<DoctorInfoPage> createState() => _DoctorInfoPageState();
}

class _DoctorInfoPageState extends State<DoctorInfoPage> {
  late Future<DoctorResponseLoginModels> _loginFuture;

  @override
  void initState() {
    super.initState();
    // 替换为实际的请求参数
    _loginFuture = APIService().register(DoctorRequestLoginModels(
        code: "your_code", 
        username: "your_username", 
        password: "your_password"));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color.fromRGBO(249, 249, 249, 10),
      body: Column(
        children: [
          Expanded(
            child: Container(
              height: 150.0,
              width: 150.0,
              color: Colors.grey.shade100,
              child: FutureBuilder<DoctorResponseLoginModels>(
                future: _loginFuture,
                builder: (context, snapshot) {
                  switch (snapshot.connectionState) {
                    case ConnectionState.waiting:
                      return const Center(child: Text('加载中....'));
                    case ConnectionState.done:
                      if (snapshot.hasError) {
                        return Center(child: Text('错误: ${snapshot.error}'));
                      } else if (snapshot.hasData) {
                        final data = snapshot.data!;
                        return Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            Text('医生姓名: ${data.doctorName ?? "无数据"}'),
                            Text('联系电话: ${data.contactNo ?? "无数据"}'),
                            Text('邮箱: ${data.emailId ?? "无数据"}'),
                            Text('角色: ${data.role ?? "无数据"}'),
                          ],
                        );
                      } else {
                        return const Center(child: Text('无返回数据'));
                      }
                    default:
                      return const Center(child: Text('请求中...'));
                  }
                },
              ),
            ),
          ),
        ],
      ),
    );
  }
}

2. 处理空值安全

响应模型的字段都是可空类型,直接用!强制解包会引发空指针异常,建议用??设置默认值。

3. 跨类传递数据的其他方式

如果需要在多个类间共享数据,可选择两种方式:

  • 构造函数传递:将获取到的DoctorResponseLoginModels实例通过构造函数传给目标Widget
class DoctorDisplayWidget extends StatelessWidget {
  final DoctorResponseLoginModels doctorData;

  const DoctorDisplayWidget({super.key, required this.doctorData});

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('姓名: ${doctorData.doctorName ?? "未知"}'),
        Text('所属科室: ${doctorData.department ?? "未知"}'),
      ],
    );
  }
}

// 在获取数据后跳转传递
// 示例:在FutureBuilder的done分支中
Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => DoctorDisplayWidget(doctorData: snapshot.data!),
  ),
);
  • 状态管理工具:使用Provider、Riverpod等全局状态管理工具,将数据存入全局状态,在任意Widget中读取。

内容的提问来源于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.15 12:50:25