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

Flutter中调用API及多API串联传参实现方案咨询

实现步骤与代码示例

首先,你的需求核心是API B的调用依赖于API A选中的下拉框值,所以不能像你现在这样用两个独立的FutureBuilder并行请求。我们需要用StatefulWidget来维护选中状态,只有当用户选择了API A的选项后,才触发API B的请求。

具体实现思路:

  • 用StatefulWidget保存三个关键状态:
    • API A返回的下拉选项数据
    • 用户选中的下拉框值
    • API B的请求Future(选中值变化时更新这个Future)
  • 先通过FutureBuilder加载API A的数据,渲染下拉框
  • 当下拉框选项改变时,更新选中值,并发起API B的请求
  • 再用另一个FutureBuilder根据API B的请求状态展示结果

完整代码示例:

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

// 假设API A返回的是包含id和名称的列表(比如城市列表)
class ApiAData {
  final String id;
  final String name;

  ApiAData({required this.id, required this.name});

  factory ApiAData.fromJson(Map<String, dynamic> json) {
    return ApiAData(
      id: json['id'],
      name: json['name'],
    );
  }
}

// 假设API B返回的是选中项对应的关联数据(比如城市景点列表)
class ApiBData {
  final String id;
  final String title;

  ApiBData({required this.id, required this.title});

  factory ApiBData.fromJson(Map<String, dynamic> json) {
    return ApiBData(
      id: json['id'],
      title: json['title'],
    );
  }
}

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

  @override
  State<ApiChainExample> createState() => _ApiChainExampleState();
}

class _ApiChainExampleState extends State<ApiChainExample> {
  // API A的请求Future,页面初始化时触发
  late Future<List<ApiAData>> _apiAFuture;
  // 用户选中的API A数据项
  ApiAData? _selectedItem;
  // API B的请求Future,选中值变化后才赋值
  Future<List<ApiBData>>? _apiBFuture;

  @override
  void initState() {
    super.initState();
    // 页面加载时先请求API A获取下拉选项
    _apiAFuture = _fetchApiA();
  }

  // 请求API A的函数
  Future<List<ApiAData>> _fetchApiA() async {
    final response = await http.get(Uri.parse('你的API A地址'));
    if (response.statusCode == 200) {
      List<dynamic> data = json.decode(response.body);
      return data.map((item) => ApiAData.fromJson(item)).toList();
    } else {
      throw Exception('加载API A数据失败');
    }
  }

  // 请求API B的函数,参数为API A选中项的id
  Future<List<ApiBData>> _fetchApiB(String paramId) async {
    final response = await http.get(Uri.parse('你的API B地址?param=$paramId'));
    if (response.statusCode == 200) {
      List<dynamic> data = json.decode(response.body);
      return data.map((item) => ApiBData.fromJson(item)).toList();
    } else {
      throw Exception('加载API B数据失败');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('API联动示例')),
      body: SafeArea(
        child: Form(
          child: ListView(
            padding: const EdgeInsets.all(16),
            children: [
              // 加载API A数据并渲染下拉框
              FutureBuilder<List<ApiAData>>(
                future: _apiAFuture,
                builder: (context, snapshot) {
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return const CircularProgressIndicator();
                  } else if (snapshot.hasError) {
                    return Text('错误:${snapshot.error}');
                  } else if (!snapshot.hasData || snapshot.data!.isEmpty) {
                    return const Text('API A无数据');
                  } else {
                    return DropdownButtonFormField<ApiAData>(
                      value: _selectedItem,
                      hint: const Text('请选择一项'),
                      items: snapshot.data!.map((item) {
                        return DropdownMenuItem<ApiAData>(
                          value: item,
                          child: Text(item.name),
                        );
                      }).toList(),
                      onChanged: (ApiAData? newValue) {
                        setState(() {
                          _selectedItem = newValue;
                          // 选中值变化时,发起API B请求
                          if (newValue != null) {
                            _apiBFuture = _fetchApiB(newValue.id);
                          } else {
                            _apiBFuture = null;
                          }
                        });
                      },
                    );
                  }
                },
              ),
              const SizedBox(height: 20),
              // 加载并展示API B的数据
              if (_apiBFuture != null)
                FutureBuilder<List<ApiBData>>(
                  future: _apiBFuture,
                  builder: (context, snapshot) {
                    if (snapshot.connectionState == ConnectionState.waiting) {
                      return const CircularProgressIndicator();
                    } else if (snapshot.hasError) {
                      return Text('错误:${snapshot.error}');
                    } else if (!snapshot.hasData || snapshot.data!.isEmpty) {
                      return const Text('API B无数据');
                    } else {
                      return ListView.builder(
                        shrinkWrap: true,
                        physics: const NeverScrollableScrollPhysics(),
                        itemCount: snapshot.data!.length,
                        itemBuilder: (context, index) {
                          final item = snapshot.data![index];
                          return ListTile(
                            title: Text(item.title),
                            subtitle: Text(item.id),
                          );
                        },
                      );
                    }
                  },
                ),
            ],
          ),
        ),
      ),
    );
  }
}

关键细节说明:

  • 用initState初始化API A的请求,保证页面加载时就开始获取下拉选项
  • DropdownButtonFormField的onChanged回调是核心逻辑:选中新值后更新状态,并触发API B的请求
  • API B的FutureBuilder只在_apiBFuture不为null时渲染,避免初始状态下的空请求
  • 处理了加载中、错误、无数据等多种状态,提升用户体验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 09:04:11