如何在Flutter中通过代码生成动态下拉菜单并收集数据
Flutter 动态生成多个下拉菜单并收集选中数据方案
核心实现思路
- 用列表维护所有下拉菜单的选中状态,每点击一次添加按钮,就往列表里插入一个默认选中值(比如
null或第一个选项) - 通过遍历这个列表,动态生成对应数量的
DropdownButton组件 - 每个下拉菜单的
onChanged回调更新对应索引位置的选中值,实现状态同步
完整可运行代码
import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Dynamic Dropdowns', theme: ThemeData(primarySwatch: Colors.blue), home: const DynamicDropdownScreen(), ); } } class DynamicDropdownScreen extends StatefulWidget { const DynamicDropdownScreen({super.key}); @override State<DynamicDropdownScreen> createState() => _DynamicDropdownScreenState(); } class _DynamicDropdownScreenState extends State<DynamicDropdownScreen> { // 存储所有下拉菜单的选中值,索引对应下拉菜单的位置 final List<String?> _selectedValues = []; // 下拉菜单的可选选项 final List<String> _dropdownOptions = ['Option 1', 'Option 2', 'Option 3', 'Option 4']; // 添加新的下拉菜单 void _addNewDropdown() { setState(() { _selectedValues.add(null); // 默认未选中任何选项 }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('动态下拉菜单示例')), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 添加按钮 ElevatedButton( onPressed: _addNewDropdown, child: const Text('添加下拉菜单'), style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12), backgroundColor: Colors.green, foregroundColor: Colors.white, ), ), const SizedBox(height: 20), // 动态生成的下拉菜单列表 Expanded( child: ListView.builder( itemCount: _selectedValues.length, itemBuilder: (context, index) { return Padding( padding: const EdgeInsets.only(bottom: 12.0), child: DropdownButtonFormField<String>( value: _selectedValues[index], hint: const Text('选择一个选项'), items: _dropdownOptions.map((option) { return DropdownMenuItem( value: option, child: Text(option), ); }).toList(), onChanged: (newValue) { setState(() { _selectedValues[index] = newValue; }); }, decoration: InputDecoration( border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), ), contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), ), ), ); }, ), ), // 显示所有选中的数据 const SizedBox(height: 20), Text( '已选中的数据:', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), const SizedBox(height: 8), Text( _selectedValues.map((val) => val ?? '未选择').join(', '), style: const TextStyle(fontSize: 14), ), ], ), ), ); } }
关键代码说明
- 状态管理:用
List<String?> _selectedValues存储每个下拉菜单的选中值,索引和下拉菜单的位置一一对应,确保修改时能精准更新对应下拉的状态 - 动态生成:通过
ListView.builder遍历_selectedValues列表,自动生成对应数量的下拉菜单,避免手动维护多个独立状态变量 - UI匹配:使用
DropdownButtonFormField替代基础DropdownButton,配合InputDecoration实现带边框的输入框样式,和示例GIF的UI效果一致;添加按钮设置了绿色背景,符合常见的添加操作按钮样式 - 数据收集:底部的文本组件实时展示所有下拉菜单的选中值,你也可以根据需求将
_selectedValues数据用于提交、存储等后续操作
内容的提问来源于stack exchange,提问作者Onalo Joseph
相关产品推荐
相关产品推荐

