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

Flutter中如何将API返回数据填充到Dropdown下拉列表

实现方案

你现有代码已经完成了API请求逻辑,核心问题是DropdownButton仍绑定本地硬编码的测试列表,没有对接接口返回的数据,同时缺少异步加载状态处理、类型声明不规范,会导致运行报错。

核心修改点

  • 删除硬编码的测试用items列表、测试初始值dropdownvalue = 'Item 1'
  • 为列表补充明确的类型声明,避免动态类型引发的异常
  • 增加加载状态判断:接口数据返回前显示加载指示器,避免下拉框初始值不存在触发报错
  • 遍历接口返回的categoryItemlist生成下拉选项,目标接口返回的每一项是包含ClassCode、ClassName字段的对象,默认展示分类名称ClassName即可

修复后可直接运行的代码

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter DropDownButton',
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: const MyHomePage(),
      debugShowCheckedModeBanner: false,
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // 下拉框选中值
  String? selectedValue;
  // 接口返回的分类列表,明确类型避免动态类型错误
  List<Map<String, dynamic>> categoryItemlist = [];
  // 接口加载状态标记
  bool isLoading = true;

  // 请求分类接口数据
  Future<void> getAllCategory() async {
    var baseUrl = "https://gssskhokhar.com/api/classes/";
    try {
      http.Response response = await http.get(Uri.parse(baseUrl));
      if (response.statusCode == 200) {
        List<dynamic> jsonData = json.decode(response.body);
        setState(() {
          categoryItemlist = jsonData.cast<Map<String, dynamic>>();
          // 数据加载完成后默认选中第一个分类
          selectedValue = categoryItemlist.first['ClassName'].toString();
          isLoading = false;
        });
      }
    } catch (e) {
      setState(() {
        isLoading = false;
      });
      print("接口请求失败:$e");
    }
  }

  @override
  void initState() {
    super.initState();
    getAllCategory();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("DropDown List"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // 加载中显示进度指示器,加载完成显示下拉框
            isLoading
                ? const CircularProgressIndicator()
                : DropdownButton<String>(
                    value: selectedValue,
                    icon: const Icon(Icons.keyboard_arrow_down),
                    // 遍历接口返回的分类列表生成下拉选项
                    items: categoryItemlist.map((item) {
                      return DropdownMenuItem<String>(
                        value: item['ClassName'].toString(),
                        child: Text(item['ClassName'].toString()),
                      );
                    }).toList(),
                    // 选中选项后更新状态
                    onChanged: (String? newValue) {
                      setState(() {
                        selectedValue = newValue;
                      });
                    },
                  ),
          ],
        ),
      ),
    );
  }
}

扩展说明

  • 如果业务需要传分类编码ClassCode作为参数,只需要把DropdownMenuItem的value字段替换为item['ClassCode'].toString()即可,child属性仍保留显示ClassName
  • 可以在catch块中自定义错误提示组件,替换默认的加载失败白屏问题
  • 如果需要选中后拿到完整的分类对象,可以把选中值类型改为Map<String, dynamic>,同步调整DropdownMenuItem的泛型和value值即可

正常运行效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 04:27:16