Flutter接入Firebase获取项目文档ID及DropdownButton报错问题咨询
错误根因
你遇到的类型错误核心是DropdownButton<Project>要求value属性为Project类型,但你当前selectedProject存储的是String类型的项目名称,二者类型不匹配。同时选中后无法显示选中项是因为Project类默认按引用判断相等,两个属性完全相同的实例会被判定为不同对象。
修复步骤
- 调整
selectedProject的类型定义,直接存储Project实例而非单独存储名称和ID - 修改
onChanged回调的赋值逻辑,直接将选中的Project对象赋值给selectedProject - 为
Project类重写==运算符和hashCode,让下拉组件可以按属性匹配选中的项目 - 修正
DropdownButton的value属性赋值,直接传入selectedProject
修复后完整代码
import 'package:flutter/material.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; // 调整类型为可空Project Project? selectedProject; DocumentSnapshot? snap; class MyTest extends StatefulWidget { const MyTest({Key? key}) : super(key: key); @override _MyTestState createState() => _MyTestState(); } class _MyTestState extends State<MyTest> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('test'), actions: <Widget>[ IconButton( icon: const Icon( Icons.add_circle_outline, color: Colors.white, ), onPressed: () { // 后续保存时直接取selectedProject?.id和selectedProject?.name即可 debugPrint("选中的项目ID:${selectedProject?.id}"); debugPrint("选中的项目名称:${selectedProject?.name}"); }, ), ], ), body: Padding( padding: const EdgeInsets.fromLTRB(8.0, 3.0, 0.0, 0.0), child: StreamBuilder<QuerySnapshot>( stream: FirebaseFirestore.instance .collection('Users') .doc(FirebaseAuth.instance.currentUser?.uid) .collection('projects') .snapshots(), builder: (context, snapshot) { if (!snapshot.hasData) { return const Text("Loading....."); } else { List<DropdownMenuItem<Project>> goalItems = []; for (int i = 0; i < snapshot.data!.docs.length; i++) { snap = snapshot.data!.docs[i]; goalItems.add( DropdownMenuItem( value: Project(snap!.id, snap!['project_Name']), child: SizedBox( width: MediaQuery .of(context) .size .width * 0.89, child: Text( snap!['project_Name'], style: const TextStyle(color: Colors.black), ), ), ), ); } return Row( children: <Widget>[ DropdownButton<Project>( items: goalItems, onChanged: (Project? pro) { setState(() { // 直接赋值整个Project对象 selectedProject = pro; }); }, // value直接传Project实例 value: selectedProject, isExpanded: false, hint: const Text('test', style: TextStyle(color: Color( 0xff29B6F6)), ), ) ]); } }), ), ); } } class Project { final String id; final String name; Project(this.id, this.name); // 重写相等判断,按id和name判断两个实例是否相等 @override bool operator ==(Object other) => identical(this, other) || other is Project && runtimeType == other.runtimeType && id == other.id && name == other.name; // 对应重写hashCode @override int get hashCode => id.hashCode ^ name.hashCode; }
内容的提问来源于stack exchange,提问作者Laurent Thomas
相关产品推荐
相关产品推荐

