我正在从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);
},),
当用户选择一个项目时,它仍显示默认值
答案 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,下面的示例对我来说是完美的。
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 方法。它会让你体现价值。
谢谢!