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

Flutter中如何将API参数接入Dropdown组件?求实现示例

实现Dropdown选中值作为API参数发起请求的示例

核心思路

你的API需要int类型的semester参数,不能直接用字符串列表绑定Dropdown,必须把显示文本和对应API参数值绑定,选中后用匹配的数值发起请求。

步骤1:定义绑定参数的学期选项

替换原静态字符串列表,改用包含显示文本与对应参数值的结构:

// 绑定学期显示文本与API需要的int参数
List<Map<String, dynamic>> semesterOptions = [
  {"text": "第1学期", "value": 1},
  {"text": "第2学期", "value": 2},
  {"text": "第3学期", "value": 3},
  {"text": "第4学期", "value": 4},
  {"text": "第5学期", "value": 5},
  {"text": "第6学期", "value": 6},
];

int selectedSemester = 1; // 默认选中第1学期
List<Data> data = [];
bool isLoading = false; // 加载状态标记

步骤2:修改Dropdown组件适配参数绑定

调整Dropdown的选项生成与选中逻辑,确保存储的是API所需的int参数:

Container(
  padding: const EdgeInsets.only(left: 12, right: 8),
  width: double.infinity,
  height: 50,
  decoration: BoxDecoration(
    color: Colors.white,
    boxShadow: [
      BoxShadow(
        color: Colors.grey.withOpacity(0.2),
        spreadRadius: 1,
        blurRadius: 9,
        offset: const Offset(1, 2),
      ),
    ],
  ),
  child: DropdownButtonHideUnderline(
    child: DropdownButton<int>(
      value: selectedSemester,
      hint: const Text("选择学期"),
      onChanged: (int? newValue) {
        if (newValue != null) {
          setState(() {
            selectedSemester = newValue;
          });
          // 可选:选中后立即发起请求,替代按钮触发
          // fetchNilaiMahasiswa();
        }
      },
      items: semesterOptions.map((option) {
        return DropdownMenuItem<int>(
          value: option["value"],
          child: Text(option["text"]),
        );
      }).toList(),
    ),
  ),
),
// 添加请求触发按钮(避免频繁请求)
ElevatedButton(
  onPressed: isLoading ? null : fetchNilaiMahasiswa,
  child: isLoading ? const CircularProgressIndicator(size: 20) : const Text("获取成绩"),
),

步骤3:完善API请求与状态更新

封装请求方法,处理加载状态、数据更新与异常捕获:

Future<void> fetchNilaiMahasiswa() async {
  setState(() {
    isLoading = true;
  });

  try {
    NilaiMahasiswa result = await getNilaiMahasiswa(selectedSemester);
    setState(() {
      data = result.data; // 假设NilaiMahasiswa包含Data类型的列表字段
      isLoading = false;
    });
  } catch (e) {
    setState(() {
      isLoading = false;
    });
    // 异常提示,可替换为弹窗
    print("请求失败: $e");
  }
}

// 保留你原有的API请求方法
Future<NilaiMahasiswa> getNilaiMahasiswa(int semester) async {
  String url = Constant.baseURL;
  String token = await UtilSharedPreferences.getToken();
  final response = await http.get(
    Uri.parse('$url/auth/mhs_siakad/transkrip_nilai?semester=$semester'),
    headers: {'Authorization': 'Bearer $token'},
  );

  print(response.statusCode);
  print(response.body);
  if (response.statusCode == 200) {
    return NilaiMahasiswa.fromJson(jsonDecode(response.body));
  } else {
    throw Exception('获取成绩失败');
  }
}

完整StatefulWidget示例

将以上代码整合为完整页面:

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
// 导入你的Constant、UtilSharedPreferences、NilaiMahasiswa、Data类

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

  @override
  State<NilaiMahasiswaPage> createState() => _NilaiMahasiswaPageState();
}

class _NilaiMahasiswaPageState extends State<NilaiMahasiswaPage> {
  List<Map<String, dynamic>> semesterOptions = [
    {"text": "第1学期", "value": 1},
    {"text": "第2学期", "value": 2},
    {"text": "第3学期", "value": 3},
    {"text": "第4学期", "value": 4},
    {"text": "第5学期", "value": 5},
    {"text": "第6学期", "value": 6},
  ];

  int selectedSemester = 1;
  List<Data> data = [];
  bool isLoading = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('学生成绩查询')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            // Dropdown组件
            Container(
              padding: const EdgeInsets.only(left: 12, right: 8),
              width: double.infinity,
              height: 50,
              decoration: BoxDecoration(
                color: Colors.white,
                boxShadow: [
                  BoxShadow(
                    color: Colors.grey.withOpacity(0.2),
                    spreadRadius: 1,
                    blurRadius: 9,
                    offset: const Offset(1, 2),
                  ),
                ],
              ),
              child: DropdownButtonHideUnderline(
                child: DropdownButton<int>(
                  value: selectedSemester,
                  hint: const Text("选择学期"),
                  onChanged: (int? newValue) {
                    if (newValue != null) {
                      setState(() {
                        selectedSemester = newValue;
                      });
                    }
                  },
                  items: semesterOptions.map((option) {
                    return DropdownMenuItem<int>(
                      value: option["value"],
                      child: Text(option["text"]),
                    );
                  }).toList(),
                ),
              ),
            ),
            const SizedBox(height: 20),
            // 请求按钮
            ElevatedButton(
              onPressed: isLoading ? null : fetchNilaiMahasiswa,
              style: ElevatedButton.styleFrom(
                minimumSize: const Size(double.infinity, 50),
              ),
              child: isLoading 
                  ? const CircularProgressIndicator(color: Colors.white, size: 20) 
                  : const Text("获取成绩", style: TextStyle(fontSize: 16)),
            ),
            const SizedBox(height: 20),
            // 数据展示区域
            Expanded(
              child: isLoading 
                  ? const Center(child: CircularProgressIndicator())
                  : ListView.builder(
                      itemCount: data.length,
                      itemBuilder: (context, index) {
                        // 根据你的Data类结构自定义列表项
                        return ListTile(
                          title: Text(data[index].mataKuliah), // 示例字段
                          subtitle: Text('成绩: ${data[index].nilai}'), // 示例字段
                        );
                      },
                    ),
            ),
          ],
        ),
      ),
    );
  }

  Future<void> fetchNilaiMahasiswa() async {
    setState(() {
      isLoading = true;
    });

    try {
      NilaiMahasiswa result = await getNilaiMahasiswa(selectedSemester);
      setState(() {
        data = result.data;
        isLoading = false;
      });
    } catch (e) {
      setState(() {
        isLoading = false;
      });
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('请求失败: $e')),
        );
      }
    }
  }

  Future<NilaiMahasiswa> getNilaiMahasiswa(int semester) async {
    String url = Constant.baseURL;
    String token = await UtilSharedPreferences.getToken();
    final response = await http.get(
      Uri.parse('$url/auth/mhs_siakad/transkrip_nilai?semester=$semester'),
      headers: {'Authorization': 'Bearer $token'},
    );

    print(response.statusCode);
    print(response.body);
    if (response.statusCode == 200) {
      return NilaiMahasiswa.fromJson(jsonDecode(response.body));
    } else {
      throw Exception('服务器返回错误: ${response.statusCode}');
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 20:45:32