Par*_*erd 5 dart firebase flutter google-cloud-firestore
我是 Flutter 的新手,但我正在尝试创建一个 DropdownButtonFormField 并且它不起作用。我收到一个错误,说我有重复的值。有趣的是,我没有一个包含重复值的列表。我在 SO 上发现了一个类似的问题,解决方案说用一个值启动字符串,并且用户正在复制一个列表项,但我对另一个列表有一个类似的解决方案,它似乎工作正常。我无法弄清楚为什么它在这里不起作用。任何帮助是极大的赞赏。
错误信息:
There should be exactly one item with [DropdownButton]'s value: 0.
Either zero or 2 or more [DropdownMenuItem]s were detected with the same value
'package:flutter/src/material/dropdown.dart':
Failed assertion: line 1411 pos 15: 'items == null || items.isEmpty || value == null ||
items.where((DropdownMenuItem<T> item) {
return item.value == value;
}).length == 1'
The relevant error-causing widget was:
StreamBuilder<UserProfile>
Run Code Online (Sandbox Code Playgroud)
ProfileForm 类:
final List<String> accountType = ['Educator', 'School Administrator', 'Parent'];
String _currentAccountType;
@override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
return StreamBuilder<UserProfile>(
stream: DatabaseService(uid: user.uid).userProfileData,
builder: (context, snapshot) {
if (snapshot.hasData) {
UserProfile userProfileData = snapshot.data;
return Form(
key: _formKey,
child: Column(
children: <Widget>[
SizedBox(height: 20.0),
DropdownButtonFormField(
decoration: textInputDecoration,
value: _currentAccountType ?? userProfileData.accountType,
items: accountType.map((accountType) {
return DropdownMenuItem(
value: accountType,
child: Text(accountType),
);
}).toList(),
onChanged: (val) {
setState(() {
_currentAccountType = val;
});
},
),
Run Code Online (Sandbox Code Playgroud)
数据库类
class DatabaseService {
final String uid;
DatabaseService({this.uid});
final CollectionReference userProfileCollection =
Firestore.instance.collection('user_profile');
Future updateUserProfile(
String accountType,
String birthDate,
String courseName,
String dateJoined,
String email,
String firstName,
String lastName,
String schoolName,
String title) async {
return await userProfileCollection.document(uid).setData({
'accountType': accountType,
'birthDate': birthDate,
'courseName': courseName,
'dateJoined': dateJoined,
'email': email,
'firstName': firstName,
'lastName': lastName,
'schoolName': schoolName,
'title': title,
});
}
//User Profile from snapshot
List<Profile> _userProfileListFromSnapshot(QuerySnapshot snapshot) {
return snapshot.documents.map((doc) {
return Profile(
accountType: doc.data['accountType'] ?? '',
birthDate: doc.data['birthDate'] ?? '',
courseName: doc.data['courseName'] ?? '',
dateJoined: doc.data['dateJoined'] ?? '',
email: doc.data['email'] ?? '',
firstName: doc.data['firstName'] ?? '',
lastName: doc.data['lastName'] ?? '',
schoolName: doc.data['schoolName'] ?? '',
title: doc.data['title'] ?? '',
);
}).toList();
}
UserProfile _userProfileFromSnapshot(DocumentSnapshot snapshot) {
return UserProfile(
uid: uid,
accountType: snapshot.data['accountType'],
birthDate: snapshot.data['birthDate'],
courseName: snapshot.data['courseName'],
dateJoined: snapshot.data['dateJoined'],
email: snapshot.data['email'],
firstName: snapshot.data['firstName'],
lastName: snapshot.data['lastName'],
schoolName: snapshot.data['schoolName'],
title: snapshot.data['title'],
);
}
Stream<List<Profile>> get userProfile {
return userProfileCollection.snapshots().map(_userProfileListFromSnapshot);
}
Stream<UserProfile> get userProfileData {
return userProfileCollection
.document(uid)
.snapshots()
.map(_userProfileFromSnapshot);
}
}
Run Code Online (Sandbox Code Playgroud)
userProfileData.accountType 是“0”,不是“教育者”或“学校管理员”或“家长”。
成功:值必须在 items.value 中
final List<String> accountType = ['Educator', 'School Administrator', 'Parent'];
DropdownButtonFormField(
decoration: textInputDecoration,
value: accountType[0],
items: accountType.map((accountType) {
return DropdownMenuItem(
value: accountType,
child: Text(accountType),
);
}).toList(),
onChanged: (val) {
setState(() {
_currentAccountType = val;
});
},
),
Run Code Online (Sandbox Code Playgroud)
失败:应该只有一个带有[DropdownButton]值的项目:哈哈哈
final List<String> accountType = ['Educator', 'School Administrator', 'Parent'];
DropdownButtonFormField(
decoration: textInputDecoration,
value: 'hahaha',
items: accountType.map((accountType) {
return DropdownMenuItem(
value: accountType,
child: Text(accountType),
);
}).toList(),
onChanged: (val) {
setState(() {
_currentAccountType = val;
});
},
),
Run Code Online (Sandbox Code Playgroud)
小智 6
就我而言,以下更改解决了错误:
错误场景:
var itemList=['Alpha','Beta','Cat'];
var itemSelected='Zebra';
Run Code Online (Sandbox Code Playgroud)
工作场景:
var itemList=['Alpha','Beta','Cat'];
var itemSelected='Cat'; //Can be Alpha, Beta or Cat but not any other value
Run Code Online (Sandbox Code Playgroud)
下拉小部件代码:
DropdownButton<String>(
items: itemList.map((String singleItem){
return DropdownMenuItem<String>(
value: singleItem,
child:Text(singleItem)
);
}).toList(),
onChanged: (String itemChosen){
setState(() {
this.itemSelected=itemChosen;
});
},
value:itemSelected ,
),
Run Code Online (Sandbox Code Playgroud)
让“itemSelected”变量值与列表中的元素之一相同解决了我的问题。
同时使用 'hint:' 和 'value:' 似乎有些冲突。我的方法是在小部件的状态中添加一个全局 _selected :
bool _selected;
Run Code Online (Sandbox Code Playgroud)
然后在 DropdownButton 本身:
value: _selected ? _userChoice: null,
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您实际上会在设置项值后使用其中一个值。
这是取自一些训练代码的完整示例(请原谅我的愚蠢;)
class FavoriteCity extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _FavoriteCityState();
}
}
class _FavoriteCityState extends State<FavoriteCity> {
String nameCity = '';
String _loveLevel = '';
bool _selected = false;
var _howMuchLoved = ['A little', 'So so', 'Quite a bit', 'A lot', 'Greatly'];
@override
Widget build(BuildContext context) {
print('Widget Built');
return Scaffold(
appBar: AppBar(
title: Text('Favorite city app'),
elevation: 8.0,
),
body: Container(
margin: EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
TextField(
onSubmitted: (String userInput) {
setState(() {
print('State rebuilt');
nameCity = userInput;
});
},
),
DropdownButton<String>(
hint: Text('How much do you love the city?'),
items: _howMuchLoved.map((String myMenuItem) {
return DropdownMenuItem<String>(
value: myMenuItem,
child: Text(myMenuItem),
);
}).toList(),
onChanged: (String valueSelectedByUser) {
_dropDownItemSelected(valueSelectedByUser);
},
value: _selected ? _loveLevel : null,
isDense: true,
),
Padding(
padding: EdgeInsets.all(20.0),
child: Text(
'Your favorite city is $nameCity ! \n ... and you love it $_loveLevel',
style: TextStyle(
fontSize: 20.0,
fontStyle: FontStyle.italic,
),
),
),
],
),
),
);
}
void _dropDownItemSelected(String valueSelectedByUser) {
setState(() {
this._loveLevel = valueSelectedByUser;
_selected = true;
});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8489 次 |
| 最近记录: |