Flutter 不显示下拉选择

Posted

技术标签:

【中文标题】Flutter 不显示下拉选择【英文标题】:Dropdown selection not displaying with Flutter 【发布时间】:2019-02-08 14:27:18 【问题描述】:

我从 JSON 中获取项目并在下拉列表中显示它们。当该人从下拉列表中选择一个项目时,我得到了选择,但所选项目没有改变。

例如,我们在列表中有 (tokyo, paris, new york)。默认选择是东京。当该人选择巴黎时,我明白了,但下拉列表中的选择没有改变。

这是我的代码:

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

当人选择一个项目时,它仍然显示默认值。

【问题讨论】:

***.com/questions/51735906/… 我试过了,但还是有同样的问题 【参考方案1】:

确保您没有在 Widget 中声明 selectedValue,下面的示例非常适合我。

这是dartpad 上的工作代码,用于测试它

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

【讨论】:

如果您使用SetState 就可以了,我需要StatelessWidget 如果不执行 setState 就无法在屏幕上呈现新内容,这就是 Flutter 的工作原理,它需要通过执行 setState 来重绘小部件,您可以更改内存中的变量值但呈现更新的值在屏幕上,您需要通过调用 setState 来重绘 ui; 如果您尝试了上面的代码,它将起作用,如果您想添加新元素,只需将该元素添加到您的列表中,例如上面代码中的deviceTypes,这样新元素就会反映在下拉列表中向下,只要下拉列表在屏幕上呈现,它就会获取新列表。 我已经用工作代码的 dartpad 链接更新了答案,请检查一下 最重要的问题:“确保你没有在 Widget 中声明 selectedValue”!【参考方案2】:
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】:

这是 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;
          );
        
      )
    );
  

【讨论】:

【参考方案4】:

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

【讨论】:

【参考方案5】:

对于那些将来面临这个问题的人。使用变量将值设置为 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

【讨论】:

这让我惊醒了。直到我用了这个【参考方案6】:

因为你需要用“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()”。再见!!

【讨论】:

我认为DropdownButtonvalue 属性已更新。现在不用分配实际的String Value,您可以只使用索引来代替【参考方案7】:

在我最近的应用程序中使用了此代码并且它有效。也许您可以将其与您的代码进行比较。

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(() );
    );

【讨论】:

【参考方案8】:

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

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

【讨论】:

我忘了告诉你下拉菜单在 AlertDialog 中 @PondikpaTchabao 你有自己的对话框小部件吗?我认为此代码不适用于您的情况,因为 setState 调用正在更新构建对话框的小部件,而不是对话框。您应该创建自己的“DropdownAlertDialog”Stateful 小部件【参考方案9】:

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

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

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

谢谢!

【讨论】:

以上是关于Flutter 不显示下拉选择的主要内容,如果未能解决你的问题,请参考以下文章

DataGridViewComboBox 下拉列表不显示任何可供选择的项目,下拉不起作用

如何使已选择的选项不显示在另一个选择选项下拉 JAVASCRIPT/ANGULARJs

选择时不显示 C# 下拉列表项颜色

select下拉不显示 请选择

Vue el-select下拉框选择成功时不显示,但是当选择其他下拉框的时候,又可以成功显示

Vue el-select下拉框选择成功时不显示,但是当选择其他下拉框的时候,又可以成功显示