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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 10:09:00