下拉菜单重置值(颤振)

时间:2018-12-27 09:48:56

标签: drop-down-menu dart flutter

我有两个下拉菜单,分别是州和城市,基本上,当用户选择一个州时,它将自动设置州的城市值。当我选择州时,会出现城市的下拉列表,在我选择城市后,如果我想将州改回原来的位置,则会出现错误

“引发了另一个异常:'package:flutter / src / material / dropdown.dart':断言失败:行513 pos 15:'items == null || value == null || items.where(((DropdownMenuItem item)=> item.value == value).length == 1':不正确。“

List state = [
"Kuala Lumpur",
"Selangor",
"Johor",
"Kedah",
"Kelantan",
"Melaka",
"Negeri Sembilan",
"Pahang",
"Penang",
"Perak",
"Perlis",
"Sabah",
"Sarawak",
"Terengganu"

 ];

List kl = [
"Ampang Hilir",
"Bandar Damai Perdana",
"Bandar Menjalara",
"Bandar Tasik Selatan",
"Bangsar",
"Bangsar South",];

List sel = [
"Ampang",
"Ara Damansara",
"Balakong",
"Bandar Bukit Raja",
"Bandar Kinrara",
"Bandar Puteri Puchong",
"Bandar Sunway",
"Bandar Utama",];

@override


void initState() {
    super.initState();

_dropDownMenuStates = getDropDownMenuState();

}

List<DropdownMenuItem<String>> getDropDownMenuState() {
List<DropdownMenuItem<String>> state1 = new List();
for (String statelist in state) {
  state1.add(
      new DropdownMenuItem(value: statelist, child: new Text(statelist)));
}
return state1;


}

List<DropdownMenuItem<String>> getDropDownMenuKL() {
List<DropdownMenuItem<String>> kl1 = new List();
for (String kllist in kl) {
  kl1.add(new DropdownMenuItem(value: kllist, child: new Text(kllist)));
}
return kl1;


 }

  List<DropdownMenuItem<String>> getDropDownMenuSEL() {
    List<DropdownMenuItem<String>> sel1 = new List();
    for (String sellist in sel) {
      sel1.add(new DropdownMenuItem(value: sellist, child: new Text(sellist)));
    }
    return sel1;
  }

    Expanded(
  child: PhysicalModel(
      borderRadius:
          new BorderRadius.circular(50.0),
      color: Colors.white,
      child: new Container(
          padding: EdgeInsets.only(
              left: 10.0, right: 10.0),
          height: 40.0,
          decoration: new BoxDecoration(
              borderRadius:
                  new BorderRadius
                      .circular(50.0),
              border: new Border.all(
                width: 3.0,
                color: Colors.grey[300],
              )),
          child: new FittedBox(
            fit: BoxFit.contain,
            child: DropdownButton(
              hint: new Text(
                  allTranslations
                      .text('city')),
              value: _currentCity,
              items: _dropDownMenuCity,
              onChanged:
                  changedDropDownCity,
            ),
          ))),
),

SizedBox(
  width: 10.0,
),
Expanded(
  child: PhysicalModel(
      borderRadius:
          new BorderRadius.circular(50.0),
      color: Colors.white,
      child: new Container(
          padding: EdgeInsets.only(
              left: 10.0, right: 10.0),
          height: 40.0,
          decoration: new BoxDecoration(
              borderRadius:
                  new BorderRadius
                      .circular(50.0),
              border: new Border.all(
                width: 3.0,
                color: Colors.grey[300],
              )),
          child: new FittedBox(
            fit: BoxFit.contain,
            child: DropdownButton(
              hint: new Text(
                  allTranslations
                      .text('state')),
              value: _currentState,
              items: _dropDownMenuStates,
              onChanged:
                  changedDropDownState,
            ),
          ))),
),

void changedDropDownState(String selectedState) {
setState(() {
  _currentState = selectedState;
  if (selectedState.toString() == "Kuala Lumpur") {
    _dropDownMenuCity = getDropDownMenuKL();
  } else if (selectedState.toString() == "Selangor") {
    _dropDownMenuCity = getDropDownMenuSEL();}


});


}

  void changedDropDownCity(String selectedCity) {
    setState(() {
      _currentCity = selectedCity;
    });
  }

2 个答案:

答案 0 :(得分:1)

在设置新的城市列表之前,您需要清除 _currentCity 。 因为DropdownButtonvalue(_dropDownMenuCity)中等待有效的items(_currentCity)。

void changedDropDownState(String selectedState) {
setState(() {
  // <<<
  _dropDownMenuCity = null;
  _currentCity = null;
  // <<<

  _currentState = selectedState;

  if (selectedState.toString() == "Kuala Lumpur") {
    _dropDownMenuCity = getDropDownMenuKL();
  } else if (selectedState.toString() == "Selangor") {
    _dropDownMenuCity = getDropDownMenuSEL();
  }
});

}

https://gist.github.com/dyegovieira/a2f78d241090a77939100e380987b8a1

答案 1 :(得分:1)

我遇到了同样的问题,所以这是我能够找到的解决方案。我使用 flutter_form_builder 库,这是解决该问题的方法:

   List<String> _items = [];
   GlobalKey<FormBuilderState> _fbKey;


   FormBuilder(
                key: _fbKey,
                child: Column(
                  children: <Widget>[
                    FormBuilderDropdown(
                        attribute: "type",                            
                        onChanged: (val) {
                          setState(() {
                            /// Ici nous récuperons ledit DropDown afin de le
                            /// reset sinon l'erreur de same value va être lancé
                            final length =
                                _fbKey.currentState.fields.values.length;
                            _fbKey.currentState.fields.values
                                .elementAt(length - 1) /// Widget position
                                .currentState
                                .reset();
                            
                            if (val == "x") {
                              _items = ["1", "2"];
                            } else {
                              _items = ["10", "11"];
                            }
                          });
                        },
                        
                        items: ["x","y"].map((cpt) {
                          return DropdownMenuItem(
                              value: cpt, 
                              child: Text("$cpt"));
                        }).toList()),
                    SizedBox(height: 20),
                    FormBuilderDropdown(
                        attribute: "number",                                                                                                                                           
                        items: _items.map((cpt) {
                          return DropdownMenuItem(
                              value: cpt, child: Text("$cpt"));
                        }).toList())]))