如何将 Firestore 文档列表绑定到 Flutter 中的下拉菜单?
Posted
技术标签:
【中文标题】如何将 Firestore 文档列表绑定到 Flutter 中的下拉菜单?【英文标题】:How to bind a Firestore documents list to a Dropdown menu in Flutter? 【发布时间】:2019-03-20 06:47:52 【问题描述】:我在下拉菜单和 Firestore 方面遇到问题,如何将从 firestore 检索到的文档列表绑定到 DropdownButton?目前我遇到了这个错误:
The argument type '(Map<dynamic, dynamic>) → DropdownMenuItem<String>' can't be assigned to the parameter type '(DocumentSnapshot) → dynamic'.
我的小部件 .dart 中的代码:
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class MessageList extends StatelessWidget
MessageList(this.firestore);
final Firestore firestore;
var _mySelection;
@override
Widget build(BuildContext context)
return StreamBuilder<QuerySnapshot>(
stream: firestore.collection('preciso-modelos').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot)
if (!snapshot.hasData) return const Text('Loading...');
return new DropdownButton<String>(
isDense: true,
hint: new Text("Select"),
value: _mySelection,
onChanged: (String newValue)
print (_mySelection);
,
items: snapshot.data.documents.map((Map map)
return new DropdownMenuItem<String>(
value: map["id"].toString(),
child: new Text(
map["name"],
),
);
).toList(),
);,
);
谢谢!
【问题讨论】:
删除类型提及 Map - snapshot.data.documents.map((Map map) to snapshot.data.documents.map((map) .... 【参考方案1】:new StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('categories').snapshots(),
builder: (context, snapshot)
if (!snapshot.hasData) return const Center(
child: const CupertinoActivityIndicator(),
);
var length = snapshot.data.documents.length;
DocumentSnapshot ds = snapshot.data.documents[length - 1];
_queryCat = snapshot.data.documents;
return new Container(
padding: EdgeInsets.only(bottom: 16.0),
width: screenSize.width*0.9,
child: new Row(
children: <Widget>[
new Expanded(
flex: 2,
child: new Container(
padding: EdgeInsets.fromLTRB(12.0,10.0,10.0,10.0),
child: new Text("Category",style: textStyleBlueBold,),
)
),
new Expanded(
flex: 4,
child:new InputDecorator(
decoration: const InputDecoration(
//labelText: 'Activity',
hintText: 'Choose an category',
hintStyle: TextStyle(
color: primaryColor,
fontSize: 16.0,
fontFamily: "OpenSans",
fontWeight: FontWeight.normal,
),
),
isEmpty: _category == null,
child: new DropdownButton(
value: _category,
isDense: true,
onChanged: (String newValue)
setState(()
_category = newValue;
dropDown = false;
print(_category);
);
,
items: snapshot.data.documents.map((DocumentSnapshot document)
return new DropdownMenuItem<String>(
value: document.data['title'],
child: new Container(
decoration: new BoxDecoration(
color: primaryColor,
borderRadius: new BorderRadius.circular(5.0)
),
height: 100.0,
padding: EdgeInsets.fromLTRB(10.0, 2.0, 10.0, 0.0),
//color: primaryColor,
child: new Text(document.data['title'],style: textStyle),
)
);
).toList(),
),
),
),
],
),
);
);
【讨论】:
我觉得还是加上cmets来帮助提问者理解比较好 如何添加文档ID为key,name为value?【参考方案2】:StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('shops').snapshots(), builder: (context, snapshot)
if (!snapshot.hasData)
return Center(
child: CupertinoActivityIndicator(),
);
return Container(
padding: EdgeInsets.only(bottom: 16.0),
child: Row(
children: <Widget>[
Expanded(
flex: 2,
child: Container(
padding: EdgeInsets.fromLTRB(12.0, 10.0, 10.0, 10.0),
child: Text(
"Shop",
),
)),
new Expanded(
flex: 4,
child: DropdownButton(
value: shopId,
isDense: true,
onChanged: (valueSelectedByUser)
_onShopDropItemSelected(valueSelectedByUser);
,
hint: Text('Choose shop'),
items: snapshot.data.documents
.map((DocumentSnapshot document)
return DropdownMenuItem<String>(
value: document.data['plant_name'] +
' ' +
document.data['shop_type'],
child: Text(document.data['plant_name'] +
' ' +
document.data['shop_type']),
);
).toList(),
),
),
],
),
);
);
shopId 在构建函数之外定义。 那么onChanged的方法是:
void _onShopDropItemSelected(String newValueSelected)
setState(()
this.shopId = newValueSelected;
);
【讨论】:
以上是关于如何将 Firestore 文档列表绑定到 Flutter 中的下拉菜单?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Firestore 中获取生成的文档 ID,然后将子集合添加到其中?