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

Flutter中如何在单个函数内调用两个API获取数据与头像

解决方案:在单个函数中调用两个API获取数据

步骤1:调整数据模型(按需)

先确保DataDetails能存储头像相关信息,新增字段用于保存头像URL或二进制数据的引用:

class DataDetails {
  final String cardName;
  final String name;
  final String address;
  final String? profileImageUrl; // 存储头像URL,允许为空

  DataDetails({
    required this.cardName,
    required this.name,
    required this.address,
    this.profileImageUrl,
  });

  factory DataDetails.fromJson(Map<String, dynamic> json) {
    return DataDetails(
      cardName: json['cardName'] ?? '',
      name: json['name'] ?? '',
      address: json['address'] ?? '',
      profileImageUrl: json['profileImageUrl'] ?? '', // 若API1返回头像地址可直接用,否则后续填充
    );
  }
}

步骤2:编写同时调用双API的函数

这个函数会先请求API1拿到基础信息,再请求API2获取头像,同时处理API2的请求失败场景:

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

Future<DataDetails> getData() async {
  final userId = 34;
  String? avatarUrl;

  // 调用API1获取基础信息
  final api1Response = await http.get(Uri.parse("你的API1地址"));
  if (api1Response.statusCode != 200) {
    throw Exception('API1请求失败');
  }
  var baseData = DataDetails.fromJson(jsonDecode(api1Response.body));

  // 调用API2获取头像,包裹在try-catch里避免请求失败导致整个流程中断
  try {
    final api2Response = await http.get(Uri.parse("你的API2地址?id=$userId"));
    if (api2Response.statusCode == 200) {
      // 假设API2返回JSON格式:{"avatarUrl": "https://xxx.com/avatar.jpg"}
      final avatarJson = jsonDecode(api2Response.body);
      avatarUrl = avatarJson['avatarUrl'] ?? '';
    } else {
      print('API2请求失败,状态码:${api2Response.statusCode}');
    }
  } catch (e) {
    print('API2请求出错:$e');
  }

  // 返回合并后的数据
  return DataDetails(
    cardName: baseData.cardName,
    name: baseData.name,
    address: baseData.address,
    profileImageUrl: avatarUrl,
  );
}

步骤3:更新FutureBuilder与UI展示

替换原来的FileImage为NetworkImage,同时处理头像加载失败或无数据的情况:

FutureBuilder<DataDetails>(
  future: getData(),
  builder: (context, snapshot) {
    // 加载中状态
    if (snapshot.connectionState == ConnectionState.waiting) {
      return const Center(child: CircularProgressIndicator());
    }
    // 请求出错状态
    if (snapshot.hasError) {
      return Center(child: Text('加载失败:${snapshot.error}'));
    }
    // 无数据状态
    if (!snapshot.hasData) {
      return const Center(child: Text('暂无数据'));
    }

    final data = snapshot.data!;
    return Screenshot(
      controller: _ssController,
      child: GestureDetector(
        onTap: () {
          Navigator.push(context, MaterialPageRoute(builder: (context) => OntapView()));
        },
        child: Stack(
          children: [
            Container(
              padding: const EdgeInsets.all(10),
              width: 350,
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(15),
                color: const Color(0xffccf7ff),
              ),
              child: Column(
                children: [
                  Container(
                    padding: const EdgeInsets.all(10),
                    child: Row(
                      children: [
                        Container(
                          height: 15,
                          width: 200,
                          child: Text(
                            data.cardName,
                            style: const TextStyle(fontWeight: FontWeight.bold),
                          ),
                        ),
                      ],
                    ),
                  ),
                  const SizedBox(height: 8),
                  Row(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: [
                      CircleAvatar(
                        radius: 45,
                        backgroundColor: Colors.grey,
                        // 有头像URL时用NetworkImage,否则显示默认图标
                        backgroundImage: data.profileImageUrl?.isNotEmpty == true
                            ? NetworkImage(data.profileImageUrl!)
                            : null,
                        child: data.profileImageUrl?.isEmpty != false
                            ? const Icon(Icons.person, size: 40)
                            : null,
                      ),
                      const SizedBox(width: 10),
                      Container(
                        padding: const EdgeInsets.only(left: 20, top: 10),
                        width: 130,
                        height: 100,
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.start,
                          children: [
                            Text(
                              data.name,
                              style: const TextStyle(
                                fontSize: 22,
                                fontWeight: FontWeight.bold,
                              ),
                            ),
                            const SizedBox(height: 5),
                            Text(
                              data.address,
                              style: const TextStyle(fontSize: 12),
                            ),
                          ],
                        ),
                      ),
                    ],
                  ),
                  // 补充剩余UI组件
                ],
              ),
            ),
          ],
        ),
      ),
    );
  },
)

额外说明

  • 如果API2返回的是图片二进制数据而非URL,可将响应体转为MemoryImage使用:
    final api2Response = await http.get(Uri.parse("你的API2地址?id=$userId"));
    if (api2Response.statusCode == 200) {
      final imageBytes = api2Response.bodyBytes;
      // UI中使用MemoryImage(imageBytes)
    }
    
  • 可根据业务需求优化错误处理逻辑,比如添加重试按钮、自定义错误提示等。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 01:12:49