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

基于Flutter现有模型与API代码,用Future Builder实现id为值、role为文本的下拉按钮

实现基于RoleModel的DropdownButton

步骤1:添加状态管理变量

在State类中新增两个状态变量,分别用于存储选中的角色ID和标记数据加载状态:

int? _selectedRoleId;
bool _isLoading = true;

步骤2:初始化时加载角色数据

在initState中调用接口获取角色数据,完成后更新状态:

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

Future<void> _fetchRoles() async {
  try {
    await getRoles();
    setState(() {
      _isLoading = false;
    });
  } catch (e) {
    print('加载角色失败: $e');
    setState(() {
      _isLoading = false;
    });
  }
}

步骤3:实现DropdownButton组件

根据加载状态、数据情况渲染对应UI,核心是将每个RoleModel转为DropdownMenuItem,设置value为角色id,child为角色role文本:

Widget _buildRoleDropdown() {
  if (_isLoading) {
    return const CircularProgressIndicator();
  }

  if (roles.isEmpty) {
    return const Text('暂无角色数据');
  }

  return DropdownButton<int?>(
    value: _selectedRoleId,
    hint: const Text('选择角色'),
    onChanged: (int? newValue) {
      setState(() {
        _selectedRoleId = newValue;
      });
      // 可添加选中后的业务逻辑,比如打印选中ID
      print('选中的角色ID: $newValue');
    },
    items: roles.map((RoleModel role) {
      return DropdownMenuItem<int?>(
        value: role.id,
        child: Text(role.role ?? '未知角色'),
      );
    }).toList(),
  );
}

完整示例代码

整合所有代码到一个StatefulWidget中,可直接运行:

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

class RoleModel {
  int? id;
  String? role;

  RoleModel({this.id, this.role});
  RoleModel.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    role = json['role'];
  }
  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['id'] = id;
    data['role'] = role;
    return data;
  }
}

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

  @override
  State<RoleDropdownPage> createState() => _RoleDropdownPageState();
}

class _RoleDropdownPageState extends State<RoleDropdownPage> {
  List<RoleModel> roles = [];
  int? _selectedRoleId;
  bool _isLoading = true;

  Future<List<RoleModel>> getRoles() async {
    try {
      final response = await http
          .get(Uri.parse('https://localhost:8000/roles'));
      var data = jsonDecode(response.body.toString());
      if (response.statusCode == 200) {
        for (Map<String, dynamic> i in data) {
          roles.add(RoleModel.fromJson(i));
        }
        return roles;
      } else {
        throw Exception('Failed to load roles:$response');
      }
    } catch (e) {
      throw Exception('Failed due to: $e');
    }
  }

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

  Future<void> _fetchRoles() async {
    try {
      await getRoles();
      setState(() {
        _isLoading = false;
      });
    } catch (e) {
      print('加载角色失败: $e');
      setState(() {
        _isLoading = false;
      });
    }
  }

  Widget _buildRoleDropdown() {
    if (_isLoading) {
      return const CircularProgressIndicator();
    }

    if (roles.isEmpty) {
      return const Text('暂无角色数据');
    }

    return DropdownButton<int?>(
      value: _selectedRoleId,
      hint: const Text('选择角色'),
      onChanged: (int? newValue) {
        setState(() {
          _selectedRoleId = newValue;
        });
        print('选中的角色ID: $newValue');
      },
      items: roles.map((RoleModel role) {
        return DropdownMenuItem<int?>(
          value: role.id,
          child: Text(role.role ?? '未知角色'),
        );
      }).toList(),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('角色选择器')),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 20),
          child: _buildRoleDropdown(),
        ),
      ),
    );
  }
}

关键注意点

  • 处理role为空的情况:用role ?? '未知角色'避免文本显示异常
  • 加载状态和空数据状态的处理:提升用户体验
  • 选中值的更新:通过setState触发UI刷新

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 10:40:37