Firestore填充的DropdownButton选中项不显示问题求助
我需要DropdownButton的选中项显示为按钮文本,目前点击下拉列表中的选项后,SnackBar能正确提示选中项,但按钮文本并未更新。后续还计划通过提交按钮将选中项保存到Firestore,尚未推进到这一步。
更新:添加参考方案后出现报错。
原代码
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; class InfoScreen extends StatefulWidget { const InfoScreen({Key? key}) : super(key: key); @override State<InfoScreen> createState() => _InfoScreenState(); } class _InfoScreenState extends State<InfoScreen> { String selectedFaction = ''; @override void initState() { // TODO: implement initState super.initState(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( leading: IconButton( onPressed: () {}, icon: const Icon(Icons.person_sharp), ), elevation: 5, centerTitle: true, titleSpacing: 0, title: const Text('Info Screen'), actions: <Widget>[ IconButton( onPressed: () {}, icon: const Icon(Icons.settings), ), ], ), body: SingleChildScrollView( padding: const EdgeInsets.all(20), child: Center( child: Column( children: [ StreamBuilder<QuerySnapshot>( stream: FirebaseFirestore.instance .collection("factions") .snapshots(), builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) { if (snapshot.hasData) { final factionDatabaseSnapshot = snapshot.data!.docs; factionDatabaseSnapshot.sort( ((a, b) { return a['name'] .toLowerCase() .compareTo(b['name'].toLowerCase()); }), ); return DropdownButton( onChanged: (snap) { setState(() { selectedFaction = snap.toString(); }); final snackbarFaction = SnackBar( content: Text('Faction Selected: $selectedFaction'), ); ScaffoldMessenger.of(context) .showSnackBar(snackbarFaction); }, items: factionDatabaseSnapshot .map((DocumentSnapshot document) { return DropdownMenuItem<String>( value: document['name'], child: Text(document['name']), ); }).toList(), isExpanded: false, isDense: false, hint: const Text('Select a faction'), ); } else { return const CircularProgressIndicator(); } }, ), ], ), ), ), ); } }
解决方案
问题根源:
- DropdownButton未绑定
value属性,无法感知选中状态变化,导致按钮文本不更新 onChanged中错误调用snap.toString(),会把String类型的选中值转为Instance of 'String'这类无效内容
修改步骤:
- 给DropdownButton添加
value属性,绑定selectedFaction,让按钮自动同步选中值 - 直接将
snap赋值给selectedFaction(无需toString()) - 可选:初始化时自动选中第一个选项,避免初始空值的异常
修改后的完整代码
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; class InfoScreen extends StatefulWidget { const InfoScreen({Key? key}) : super(key: key); @override State<InfoScreen> createState() => _InfoScreenState(); } class _InfoScreenState extends State<InfoScreen> { String selectedFaction = ''; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( leading: IconButton( onPressed: () {}, icon: const Icon(Icons.person_sharp), ), elevation: 5, centerTitle: true, titleSpacing: 0, title: const Text('Info Screen'), actions: <Widget>[ IconButton( onPressed: () {}, icon: const Icon(Icons.settings), ), ], ), body: SingleChildScrollView( padding: const EdgeInsets.all(20), child: Center( child: Column( children: [ StreamBuilder<QuerySnapshot>( stream: FirebaseFirestore.instance.collection("factions").snapshots(), builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) { if (snapshot.hasData) { final factionDatabaseSnapshot = snapshot.data!.docs; factionDatabaseSnapshot.sort( ((a, b) { return a['name'].toLowerCase().compareTo(b['name'].toLowerCase()); }), ); // 初始化自动选中第一个选项(可选) if (selectedFaction.isEmpty && factionDatabaseSnapshot.isNotEmpty) { WidgetsBinding.instance.addPostFrameCallback((_) { setState(() { selectedFaction = factionDatabaseSnapshot.first['name']; }); }); } return DropdownButton<String>( // 绑定选中值,空值时显示hint value: selectedFaction.isEmpty ? null : selectedFaction, onChanged: (snap) { if (snap == null) return; setState(() { selectedFaction = snap; }); final snackbarFaction = SnackBar( content: Text('Faction Selected: $selectedFaction'), ); ScaffoldMessenger.of(context).showSnackBar(snackbarFaction); }, items: factionDatabaseSnapshot.map((DocumentSnapshot document) { return DropdownMenuItem<String>( value: document['name'], child: Text(document['name']), ); }).toList(), isExpanded: false, isDense: false, hint: const Text('Select a faction'), ); } else { return const CircularProgressIndicator(); } }, ), // 后续可添加的保存按钮示例 // ElevatedButton( // onPressed: () { // if (selectedFaction.isNotEmpty) { // FirebaseFirestore.instance.collection('user_data').add({ // 'selected_faction': selectedFaction, // 'timestamp': FieldValue.serverTimestamp(), // }); // ScaffoldMessenger.of(context).showSnackBar( // const SnackBar(content: Text('选中项已保存')), // ); // } // }, // child: const Text('保存选中项'), // ) ], ), ), ), ); } }
内容的提问来源于stack exchange,提问作者SUD
相关产品推荐
相关产品推荐

