Flutter不显示下拉选择

时间:2018-09-03 14:01:22

标签: dart flutter dropdown

我正在从json获取项目并将其显示在下拉列表中,当人们从下拉列表中选择一个项目时,我会得到选择,但所选项目不会更改。例如,我们在列表中(东京,巴黎,纽约)。默认情况下,选择东京。当人们选择巴黎时,我明白了,但下拉菜单中的选择没有改变。这是我的代码:

new DropdownButton(
                value: cities.elementAt(0),
                hint: new Text("Ville"),
                items: cities.map((String value) {
                  return new DropdownMenuItem(value: value,
                    child: new Row(
                      children: <Widget>[
                        new Icon(
                          Icons.location_city, color: Colors.deepOrange,),
                        new Text(value)
                      ],
                    ),);
                }).toList(),
                onChanged: (String value) {
                  getTravelCity(value);
                },),

当用户选择一个项目时,它仍显示默认值

9 个答案:

答案 0 :(得分:2)

这是Flutter Github中报告的错误。

正确的实现是:

class _DropdownButtonBugState extends State<DropdownButtonBug> {

  final List<String> _items = ['One', 'Two', 'Three', 'Four'].toList();

  String _selection;

  @override
  void initState() {
    _selection = _items.first;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    final dropdownMenuOptions = _items
      .map((String item) =>
        new DropdownMenuItem<String>(value: item, child: new Text(item))
      )
      .toList();

    return new Scaffold(
      body: new DropdownButton<String>(
        value: _selection,
        items: dropdownMenuOptions,
        onChanged: (s) {
          setState(() {
            _selection = s;
          });
        }
      )
    );
  }
}

答案 1 :(得分:1)

确保您没有在Widget中声明selectedValue,下面的示例对我来说是完美的。

enter image description here

var currentSelectedValue;
const deviceTypes = ["Mac", "Windows", "Mobile"];

 Widget typeFieldWidget() {
return Container(
  padding: EdgeInsets.symmetric(horizontal: 20),
  child: FormField<String>(
    builder: (FormFieldState<String> state) {
      return InputDecorator(
        decoration: InputDecoration(
            border: OutlineInputBorder(
                borderRadius: BorderRadius.circular(5.0))),
        child: DropdownButtonHideUnderline(
          child: DropdownButton<String>(
            hint: Text("Select Device"),
            value: currentSelectedValue,
            isDense: true,
            onChanged: (newValue) {
              setState(() {
                currentSelectedValue = newValue;
              });
              print(currentSelectedValue);
            },
            items: deviceTypes.map((String value) {
              return DropdownMenuItem<String>(
                value: value,
                child: Text(value),
              );
            }).toList(),
          ),
        ),
      );
    },
  ),
);
}

答案 2 :(得分:1)

This is the solution: "StatefulBuilder()"

       Future<void> AgregarContacto() async {
             String dropdownValue = 'Exento';
             return showDialog<void>(
           context: context,
           barrierDismissible: true, // user must tap button!
           builder: (BuildContext context) {
                 return StatefulBuilder(
                   builder: (BuildContext context, StateSetter setState) {
                   return AlertDialog(
                   title: Text('Agregar cliente', textAlign: TextAlign.center,),
                   content:
                     SingleChildScrollView(
                       child: ListBody(
                         children: <Widget>[
                           Center(
                             child: Material(
                               type: MaterialType.transparency,
                               child: DropdownButton<String>(
                                 items: <String>[
                                   'Responsable inscripto',
                                   'Monotributista',
                                   'Exento',
                                   'Consumidor final',
                                   'No responsable'
                                 ]
                                     .map<DropdownMenuItem<String>>((
                                     String value) {
                                   return DropdownMenuItem<String>(
                                     value: value,
                                     child: Text(value),
                                   ); //DropMenuItem
                                 }).toList(),
                                 value: dropdownValue,
                                 onChanged: (String newValue) {
                                   setState(() {
                                     dropdownValue = newValue;
                                     print("new${newValue}");
                                   }); //setState
                                 },
                                 //OnChange
                                 isExpanded: false,
                                 hint: Text('Responsable inscripto',
                                   style: TextStyle(color: Colors.black),),
                               ),
                             ), //Material
                           ), //Center
                         ],
                       ),
                     ),
                   actions: <Widget>[
                         FlatButton(
                           child: Text('Regret'),
                           onPressed: () {
                             Navigator.of(context).pop();
                          },
                       ),
                    ],
                 );
            }
            );
           },
         );
       }

答案 3 :(得分:0)

因为您需要使用“ setState((){});;”来更新“ value:”参数方法和新值必须与传递给“ onChanged:”的类型相同。我建议您这样做,因为您可以动态更改图标。

1)在文件顶部声明一个新类;

class city {
  final String name;
  final IconData icon;

  const city({
    this.name,
    this.icon,
  });
}

2)将其添加到小部件状态:

class yourState extend<myWidget>{

List<city> cities = [
    new city(name: "tokio", icon: Icons.location_city),
    new city(name: "paris", icon: Icons.location_city),
    new city(name: "new york", icon: Icons.location_city),
  ];

int index = 0;

Widget drop() {
    return DropdownButton(
        value: cities[index],
        hint: new Text("Ville"),
        items: cities.map((city value) {
          return new DropdownMenuItem(
            value: value,
            child: new Row(
              children: <Widget>[
                new Icon(
                  value.icon,
                  color: Colors.deepOrange,
                ),
                new Text(value.name)
              ],
            ),
          );
        }).toList(),
        onChanged: (city value) {
          setState(() {
            index = cities.indexOf(value);
            print(index);
          });
          //getTravelCity(value.name);
        });
  }

}

现在在需要DropDown的地方调用“ drop()”。再见!

答案 4 :(得分:0)

我在最新的应用程序中使用了此代码,并且可以正常工作。也许您可以将其与您的代码进行比较。

return DropdownButton<String>(
    style: Theme.of(context).textTheme.title,
    items: _persons.map((String val) {
      return new DropdownMenuItem<String>(
        value: val,
        child: new Container(
          child: new Card(
            child: new Row(children: <Widget>[
              new Icon(Icons.person),
              new Text(val),
            ]),
          ),
        ),
      );
    }).toList(),
    hint: new Card(
        child: new Row(children: <Widget>[
      new Icon(Icons.person),
      new Text("check"),
    ])),
    value: _selectedPerson,
    onChanged: (newVal) {
      _selectedPerson = newVal;
      setState(() {});
    });

答案 5 :(得分:0)

您将第一个城市硬编码为下拉列表的

new DropdownButton(
            value: cities.elementAt(0), //this one
...

您需要具有一些state变量才能容纳所选城市。

class YourStatefulWidgetState extends State<YourStatefulWidget> {
  @override
  initState() {
   super.initState();
   selectedCity = cities.elementAt(0)
  }

 @override
 Widget build(BuildContext context) {
   ...
   new DropdownButton(
            value: selectedCity,
            hint: new Text("Ville"),
            items: cities.map((String value) {
              return new DropdownMenuItem(value: value,
                child: new Row(
                  children: <Widget>[
                    new Icon(
                      Icons.location_city, color: Colors.deepOrange,),
                    new Text(value)
                  ],
                ),);
            }).toList(),
            onChanged: (String value) {
              setState(() {
                selectedCity = getTravelCity(value);
              });
            },),
     ...

答案 6 :(得分:0)

对于那些将来面临此问题的人。使用变量将值设置为DropdownButton,并在调用onChanged时使用setState更新变量

Expanded(child: DropdownButton<String>(
          items: cities.map((String value) {
            return DropdownMenuItem<String>(
              value: value,
              child: Text(value),
            );
          }).toList(),
          value: city,
          onChanged: (String val) {
            _onDropDownChanged(val);
          },
        ),)

使用状态更新城市变量

void _onDropDownChanged(String val) {
    setState(() {
      this.city = val;
    });
  }

有关更多信息,请查看下面的链接

https://github.com/FazalHussain/Flutter-Demo/blob/trip_cost_app/lib/main.dart

答案 7 :(得分:0)

如果选择后未更新所选值,则下拉按钮可以包装在StatefulBuilder()小部件内。

答案 8 :(得分:-1)

我厌倦了所有的选择,包括所有的颤振问题。 但是经过2个小时的搜索。我为我的 Bloc 实现的小部件找到了解决方案。

 onChanged: (Object value) {
     selectedCity = getTravelCity(value);
     setState((){}; });
        );

你可以在这里感受到不同。由于我使用某种状态填充 BlocBuilder 下的列表,因此它不允许您重建下拉菜单。所以在设置 dropdownValue 之后调用 setState 方法。它会让你体现价值。

谢谢!