[英]Selection of Item in DropdownButton causes Flutter to throw error
[英]Flutter Error when changing DropDownButton Selection
錯誤:
Failed assertion: line 609 pos 15: 'items == null ||
I/flutter (24295): items.isEmpty || value == null || items.where((DropdownMenuItem<T> item) => item.value ==
I/flutter (24295): value).length == 1': is not true.
我做了一些研究,但沒弄清楚導致問題的原因。 這是我的代碼:
class StatusList extends StatefulWidget {
@override
_StatusListState createState() => _StatusListState();
}
class _DispositionListState extends State<DispositionList> {
var _currentSelectedValue = '';
Future<RecordList> recordList;
@override
void initState() {
recordList = getRecord();
super.initState();
}
int i = 1;
List<String> statusList = List<String>();
@override
Widget build(BuildContext context) {
return FutureBuilder<RecordList>(
future: recordList,
builder: (context, snapshot) {
if (snapshot.hasData) {
String current = snapshot.data.record[0].status.trim();
statusList.add(snapshot.data.record[0].status.trim());
while (i < snapshot.data.record.length) {
if (snapshot.data.record[i].status.trim() != current) {
statusList.add(snapshot.data.record[i].status.trim());
current = snapshot.data.record[i].status.trim();
}
i++;
}
_currentSelectedValue = statusList[0]; //not set this will straight getting error
return DropdownButton(
items: statusList.map((String dropDownStringItem) {
return DropdownMenuItem<String>(
value: dropDownStringItem,
child: SizedBox(
width: 200.0,
child: Text(
dropDownStringItem,
overflow: TextOverflow.ellipsis,
),
));
}).toList(),
onChanged: (String valueSelected) {
onDropDownSelected(valueSelected);
},
value: _currentSelectedValue,
);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
});
}
void onDropDownSelected(String valueSelected) {
setState(() {
this._currentSelectedValue = valueSelected;
});
}
}
我嘗試比較recordList和onDropDownSelected中的valueSelected返回true。 甚至在沒有任何代碼的情況下調用setState時引起的問題。 誰知道基於這些代碼導致問題的原因?
補充代碼:這是我的getRecord()
Future<RecordList> getRecord() async {
String url = 'some url';
final response = await http.get(url, headers: {"Accept": "application/json"});
if (response.statusCode == 200) {
return RecordList.fromJson(json.decode(response.body));
} else {
throw Exception('Failed to load post');
}
}
class Record {
final String status;
final String disposition;
final int total;
Record({this.status, this.disposition, this.total});
factory Record.fromJson(Map<String, dynamic> json) {
return Record(
status: json['status'],
disposition: json['disposition'],
total: json['total']);
}
}
class RecordList {
final List<Record> record;
RecordList({this.record});
factory RecordList.fromJson(List<dynamic> parsedJson) {
List<Record> record = new List<Record>();
record = parsedJson.map((i) => Record.fromJson(i)).toList();
return new RecordList(
record: record,
);
}
}
可能是DropdownButton
的value
屬性的值不是item
的值之一。 value
屬性應為null
或項目值之一。
此外,也許你不需要這里的FutureBuilder
。 你可以這樣做:
class _DispositionListState extends State<DispositionList> {
bool _isLoading = true;
String _currentSelectedValue;
List<String> statusList = List<String>();
@override
void initState() {
super.initState();
_loadStatusList();
}
_loadStatusList() async {
final recordList = await getRecord();
final list = recordList.record.map((r) {
return r.status.trim();
}).toSet().toList();
setState(() {
statusList = list;
_currentSelectedValue = list.first;
_isLoading = false;
});
}
@override
Widget build(BuildContext context) {
return isLoading ? CircularProgressIndicator() : _buildDropdown();
}
Widget _buildDropdown() {
return DropdownButton(
items: statusList.map((dropDownStringItem) {
return DropdownMenuItem<String>(
value: dropDownStringItem,
child: SizedBox(
width: 200.0,
child: Text(
dropDownStringItem,
overflow: TextOverflow.ellipsis,
),
),
);
}).toList(),
onChanged: (valueSelected) {
onDropDownSelected(valueSelected);
},
value: _currentSelectedValue,
);
}
void onDropDownSelected(String valueSelected) {
setState(() {
this._currentSelectedValue = valueSelected;
});
}
}
更新:添加
.toSet()
以從statusList
過濾掉重復statusList
我認為問題是狀態列表有重復的項目。 我添加.toSet()
之前.toList()
過濾掉重復。 Set
是一組對象,其中每個對象只能出現一次。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.