Flutter - 从 Firestore 获取数据并将其显示在下拉列表中 [英] Flutter - Fetch Data from firestore and display it in a dropdown list

查看:15
本文介绍了Flutter - 从 Firestore 获取数据并将其显示在下拉列表中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to fetch data from firestore and display it in a dropdown menu. I tried declaring the list like the following:   List makes = [''] but I can’t view the data until I click on another field and the dropdown gets populated at multiple occasions. I have it in a method because eventually, I would like to create a second dropdown where there’s a condition in the database query.

例如.如果选择了 Toyota,则显示该特定品牌的所有型号.

ex. If Toyota is selected display all the models for that particular 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),
        );
      }),

推荐答案

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

Checking the snippet you've provided, it seems that the app displays two DropdownButton. To display a default selected item on the dropdown, an item should be set on value. In my approach, I've set a boolean to check if there's a need to set a default value.

此示例应用中使用的 Firestore 数据访问两个 Firestore 集合:carMakecars(包含makeModel").

The Firestore data used in this sample app accesses two Firestore collections: carMake and cars (contains 'makeModel').

carMake 合集

cars 包含makeModel"的集合

cars collection containing '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'),
                    ),
            ),
          ),
        ],
      ),
    );
  }
}

演示

这篇关于Flutter - 从 Firestore 获取数据并将其显示在下拉列表中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆