更改DropDownButton选择时出现Flutter错误

时间:2019-06-03 07:23:19

标签: flutter dart

错误:

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,
    );
  }
}

1 个答案:

答案 0 :(得分:0)

value的{​​{1}}属性的值可能不是DropdownButton的值之一。 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之前添加了.toSet(),以过滤出重复项。 .toList()是对象的集合,其中每个对象只能出现一次。