[英]Selection of Item in DropdownButton causes Flutter to throw error
我目前正在嘗試從REST API檢索數據(標簽),並使用該數據填充一個可以成功完成的下拉菜單,但是在選擇該項目時,出現以下錯誤,根據該錯誤, 這意味着“已選擇”值不是值列表的成員”:
項目== null || 值== null || items.where(((DropdownMenuItem item)=> item.value == value).length == 1':不正確。
這是在下拉菜單顯示我的選定項目之后發生的。 但是,這不是應該發生的錯誤,因為我已經完成了必要的日志記錄,以檢查數據是否確實分配給了相關列表。 誰能幫我解決這個問題? 我已經將其隔離到起源於DropdownButton的onChanged
的setState()
方法,但是似乎無法理解為什么這會引起問題。 任何幫助將不勝感激!
我的代碼如下:
class _TodosByTagsHomePageState extends State<TodosByTagsHomePage> {
Tag selectedTag;
final Logger log = new Logger('TodosByTags');
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Screen"),
),
body: ListView(
children: <Widget>[
FutureBuilder<List<Tag>> (
future: fetchTags(),
builder: (context, snapshot) {
if (snapshot.hasData) {
log.info("Tags are present");
_tagsList = snapshot.data;
return DropdownButton<Tag>(
value: selectedTag,
items: _tagsList.map((value) {
return new DropdownMenuItem<Tag>(
value: value,
child: Text(value.tagName),
);
}).toList(),
hint: Text("Select tag"),
onChanged: (Tag chosenTag) {
setState(() {
log.info("In set state");
selectedTag = chosenTag;
Scaffold.of(context).showSnackBar(new SnackBar(content: Text(selectedTag.tagName)));
});
},
) ;
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return Container(width: 0.0, height: 0.0);
}),
])
);
}
// Async method to retrieve data from REST API
Future<List<Tag>> fetchTags() async {
final response =
await http.get(REST_API_URL);
if (response.statusCode == 200) {
// If the call to the server was successful, parse the JSON
var result = compute(parseData, response.body);
return result;
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
static List<Tag> parseData(String response) {
final parsed = json.decode(response);
return (parsed["data"] as List).map<Tag>((json) =>
new Tag.fromJson(json)).toList();
}
List<Tag> _tagsList = new List<Tag>();
}
// Model for Tag
class Tag {
final String tagName;
final String id;
final int v;
Tag({this.id, this.tagName, this.v});
factory Tag.fromJson(Map<String, dynamic> json) {
return new Tag(
id: json['_id'],
tagName: json['tagName'],
v: json['__v'],
);
}
}
這樣更新代碼,我認為這樣的問題是,在FutureBuilder
中調用setState
並調用fetchTags()
將fetchTags()
移至initState()
一次即可調用
class _TodosByTagsHomePageState extends State<TodosByTagsHomePage> {
Tag selectedTag;
Future<List<Tag>> _tags;
@override
void initState() {
_tags = fetchTags();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Screen"),
),
body: ListView(children: <Widget>[
FutureBuilder<List<Tag>>(
future: _tags,
builder: (context, snapshot) {
if (snapshot.hasData) {
return DropdownButton<Tag>(
value: selectedTag,
items: snapshot.data.map((value) {
print(value);
return DropdownMenuItem<Tag>(
value: value,
child: Text(value.tagName),
);
}).toList(),
hint: Text("Select tag"),
onChanged: (Tag chosenTag) {
setState(() {
selectedTag = chosenTag;
});
},
);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return Container(width: 0.0, height: 0.0);
}),
]));
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.