首页 > 解决方案 > Flutter - 从 Firestore 获取数据并将其显示在下拉列表中

问题描述

我正在尝试从 firestore 获取数据并将其显示在下拉菜单中。我尝试如下声明列表: List make = [''] 但我无法查看数据,直到我单击另一个字段并且下拉列表在多个场合被填充。我有一个方法,因为最终,我想在数据库查询中有条件的地方创建第二个下拉列表。

前任。如果选择丰田,则显示该特定品牌的所有型号。

new StreamBuilder<QuerySnapshot>(
      stream: Firestore.instance.collection("makesModels").snapshots(),
      builder: (context, snapshot) {
        if (!snapshot.hasData) return new Text("Please wait");
        return new DropdownButton(
          items: snapshot.data.documents.map((DocumentSnapshot document) {
            return DropdownMenuItem(
                value: document.data["make"],
                child: new Text(document.data["make"]));
          }).toList(),
          value: category,
          onChanged: (value) {
            setState(() {
              category = value;
            });
          },
          hint: new Text("Makes"),
          style: TextStyle(color: Colors.black),
        );
      }),
      new StreamBuilder<QuerySnapshot>(
      stream: Firestore.instance.collection("makesModels").where('make', isEqualTo: category).snapshots(),
      builder: (context, snapshot) {

        if (!snapshot.hasData) return new Text("Please wait");
        return new DropdownButton(
          items: snapshot.data.documents.map((DocumentSnapshot document) { 
            for(int i = 0; i < document.data['models'].length; i++){

              print(document.data['models'][i]);
              return new DropdownMenuItem(
              value: document.data['models'][i],
                child: new Text(document.data['models'][i].toString()),
              );
            }   

            }).toList(),
          value: models,
          onChanged: (value) {
            print(value);

            setState(() {
              models = value;
            });
          },
          hint: new Text("Models"),
          style: TextStyle(color: Colors.black),
        );
      }),

标签: firebasefluttergoogle-cloud-firestore

解决方案


检查您提供的代码段,该应用程序似乎显示了两个DropdownButton. 要在下拉列表中显示默认选定项目,应将项目设置为value。在我的方法中,我设置了一个布尔值来检查是否需要设置默认值。

此示例应用程序中使用的 Firestore 数据访问两个 Firestore 集合:carMakecars(包含“makeModel”)。

carMake收藏

汽车制作收藏

cars包含“makeModel”的集合

在此处输入图像描述

完整的应用程序

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // Initialize Firebase
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  var carMake, carMakeModel;
  var setDefaultMake = true, setDefaultMakeModel = true;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    debugPrint('carMake: $carMake');
    debugPrint('carMakeModel: $carMakeModel');
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Column(
        children: [
          Expanded(
            flex: 1,
            child: Center(
              child: StreamBuilder<QuerySnapshot>(
                stream: FirebaseFirestore.instance
                    .collection('carMake')
                    .orderBy('name')
                    .snapshots(),
                builder: (BuildContext context,
                    AsyncSnapshot<QuerySnapshot> snapshot) {
                  // Safety check to ensure that snapshot contains data
                  // without this safety check, StreamBuilder dirty state warnings will be thrown
                  if (!snapshot.hasData) return Container();
                  // Set this value for default,
                  // setDefault will change if an item was selected
                  // First item from the List will be displayed
                  if (setDefaultMake) {
                    carMake = snapshot.data.docs[0].get('name');
                    debugPrint('setDefault make: $carMake');
                  }
                  return DropdownButton(
                    isExpanded: false,
                    value: carMake,
                    items: snapshot.data.docs.map((value) {
                      return DropdownMenuItem(
                        value: value.get('name'),
                        child: Text('${value.get('name')}'),
                      );
                    }).toList(),
                    onChanged: (value) {
                      debugPrint('selected onchange: $value');
                      setState(
                        () {
                          debugPrint('make selected: $value');
                          // Selected value will be stored
                          carMake = value;
                          // Default dropdown value won't be displayed anymore
                          setDefaultMake = false;
                          // Set makeModel to true to display first car from list
                          setDefaultMakeModel = true;
                        },
                      );
                    },
                  );
                },
              ),
            ),
          ),
          Expanded(
            flex: 1,
            child: Center(
              child: carMake != null
                  ? StreamBuilder<QuerySnapshot>(
                      stream: FirebaseFirestore.instance
                          .collection('cars')
                          .where('make', isEqualTo: carMake)
                          .orderBy("makeModel").snapshots(),
                      builder: (BuildContext context,
                          AsyncSnapshot<QuerySnapshot> snapshot) {
                        if (!snapshot.hasData) {
                          debugPrint('snapshot status: ${snapshot.error}');
                          return Container(
                            child:
                            Text(
                                'snapshot empty carMake: $carMake makeModel: $carMakeModel'),
                          );
                        }
                        if (setDefaultMakeModel) {
                          carMakeModel = snapshot.data.docs[0].get('makeModel');
                          debugPrint('setDefault makeModel: $carMakeModel');
                        }
                        return DropdownButton(
                          isExpanded: false,
                          value: carMakeModel,
                          items: snapshot.data.docs.map((value) {
                            debugPrint('makeModel: ${value.get('makeModel')}');
                            return DropdownMenuItem(
                              value: value.get('makeModel'),
                              child: Text(
                                '${value.get('makeModel')}',
                                overflow: TextOverflow.ellipsis,
                              ),
                            );
                          }).toList(),
                          onChanged: (value) {
                            debugPrint('makeModel selected: $value');
                            setState(
                              () {
                                // Selected value will be stored
                                carMakeModel = value;
                                // Default dropdown value won't be displayed anymore
                                setDefaultMakeModel = false;
                              },
                            );
                          },
                        );
                      },
                    )
                  : Container(
                      child: Text('carMake null carMake: $carMake makeModel: $carMakeModel'),
                    ),
            ),
          ),
        ],
      ),
    );
  }
}

演示

演示


推荐阅读