问题描述
我正在尝试从 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 集合:carMake
和 cars
(包含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 获取数据并将其显示在下拉列表中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!