Flutter中如何从另一个类获取下拉菜单的选中项值
问题描述
刚接触Flutter,想要从另一个类的下拉菜单组件中获取选中项的值,并将该值作为status字段存入Firestore数据库。以下是我的代码:
dropdown_menu.dart
const List<String> list = <String>[ 'item1', 'item2' ]; class DropdownButtonExample extends StatefulWidget { const DropdownButtonExample({Key? key}) : super(key: key); @override State<DropdownButtonExample> createState() => _DropdownButtonExampleState(); } class _DropdownButtonExampleState extends State<DropdownButtonExample> { String dropdownValue = list.first; String holder = ''; @override Widget build(BuildContext context) { return DropdownButton<String>( value: dropdownValue, icon: const Icon(Icons.arrow_downward), elevation: 16, style: const TextStyle(color: Colors.blueGrey), underline: Container( height: 2, color: Colors.orangeAccent, ), onChanged: (String? value) { // This is called when the user selects an item. setState(() { holder = value!; }); }, items: list.map<DropdownMenuItem<String>>((String value) { return DropdownMenuItem<String>( value: value, child: Text(value), ); }).toList(), ); } }
form.dart
class Candidateaddform extends StatefulWidget { const Candidateaddform({Key? key}) : super(key: key); @override State<Candidateaddform> createState() => _CandidateaddformState(); } class _CandidateaddformState extends State<Candidateaddform> { var candidate = FirebaseFirestore.instance.collection('testdata').doc(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Aday Formu'), leading: IconButton( icon: const Icon(Icons.arrow_back, color: Colors.black), onPressed: () => Navigator.of(context) .pushNamedAndRemoveUntil(homeRoute, (contex) => false) )), body: Column( children: [ DropdownButtonExample(), SizedBox(height: 24), ElevatedButton( onPressed: addData, child: const Text('Save'), ), ], ), ); } Future addData() async { await candidate.set({ 'status' : '', 'updatedate': FieldValue.serverTimestamp(), }).then((value) => print('added.')); } }
请问如何跨类获取下拉菜单的选中项值?
解决方案
最直接的方式是通过回调函数让子组件(DropdownButtonExample)把选中的值传递给父组件(Candidateaddform),步骤如下:
1. 修改DropdownButtonExample,添加回调参数
在DropdownButtonExample的StatefulWidget中新增一个ValueChanged<String>类型的回调属性,用于传递选中的值:
const List<String> list = <String>[ 'item1', 'item2' ]; class DropdownButtonExample extends StatefulWidget { // 新增回调函数,用于向父组件传递选中值 final ValueChanged<String>? onValueChanged; const DropdownButtonExample({Key? key, this.onValueChanged}) : super(key: key); @override State<DropdownButtonExample> createState() => _DropdownButtonExampleState(); } class _DropdownButtonExampleState extends State<DropdownButtonExample> { String dropdownValue = list.first; @override Widget build(BuildContext context) { return DropdownButton<String>( value: dropdownValue, icon: const Icon(Icons.arrow_downward), elevation: 16, style: const TextStyle(color: Colors.blueGrey), underline: Container( height: 2, color: Colors.orangeAccent, ), onChanged: (String? value) { if (value != null) { setState(() { dropdownValue = value; }); // 触发回调,将选中值传给父组件 widget.onValueChanged?.call(value); } }, items: list.map<DropdownMenuItem<String>>((String value) { return DropdownMenuItem<String>( value: value, child: Text(value), ); }).toList(), ); } }
这里移除了冗余的holder变量,直接用dropdownValue维护选中状态,选中后通过widget.onValueChanged?.call(value)完成值的传递。
2. 在Candidateaddform中接收值并写入Firestore
在父组件的状态类中新增变量存储选中的status值,使用DropdownButtonExample时传入回调更新该变量,最后在addData方法中使用这个变量:
class Candidateaddform extends StatefulWidget { const Candidateaddform({Key? key}) : super(key: key); @override State<Candidateaddform> createState() => _CandidateaddformState(); } class _CandidateaddformState extends State<Candidateaddform> { var candidate = FirebaseFirestore.instance.collection('testdata').doc(); // 存储下拉菜单选中的status值,默认选中第一个选项 String selectedStatus = list.first; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Aday Formu'), leading: IconButton( icon: const Icon(Icons.arrow_back, color: Colors.black), onPressed: () => Navigator.of(context) .pushNamedAndRemoveUntil(homeRoute, (context) => false) )), body: Column( children: [ DropdownButtonExample( // 传入回调函数,更新选中的status值 onValueChanged: (value) { setState(() { selectedStatus = value; }); }, ), const SizedBox(height: 24), ElevatedButton( onPressed: addData, child: const Text('Save'), ), ], ), ); } Future addData() async { await candidate.set({ 'status': selectedStatus, // 使用选中的值写入Firestore 'updatedate': FieldValue.serverTimestamp(), }).then((value) => print('added.')); } }
补充说明
- 这种回调方式是Flutter父子组件传值的基础方案,适合简单的组件通信场景。
- 如果后续项目复杂度提升,也可以考虑使用Provider、Riverpod等状态管理工具统一管理状态,但当前场景下回调已经足够简洁高效。
内容的提问来源于stack exchange,提问作者matto
相关产品推荐
相关产品推荐

