ShowDialog 不改变下拉列表
ShowDialog doesn't change dropdownlist
当我在 dropdownMenuItem 中更改所选项目时,我的对话框不会将其更改为我select编辑的内容。
我有一个下拉列表显示客户端可以 select,当我 select 其中一个 selected 项目没有显示在字段中时,提示保持那里。
它以“SERVIÇO:”开头,并在更改项目后保持原样。
变量获取值但在显示中没有变化。
Future<void> _addObraServico(BuildContext context) async {
return showDialog(
context: context,
child: new Dialog(
backgroundColor: blueSoftwar,
child: new Column(children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
child: Text(
"SERVIÇOS",
style: TextStyle(
fontSize: 20,
color: Colors.white,
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: new Theme(
data: Theme.of(context).copyWith(
canvasColor: orangeSoftwar,
),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black),
borderRadius: BorderRadius.all(Radius.circular(
5.0) // <--- border radius here
),
),
child: DropdownButton<String>(
isExpanded: true,
value: obraServicoDropDown,
icon: const Icon(
Icons.arrow_downward,
color: Colors.white,
),
style: const TextStyle(color: Colors.white),
underline: SizedBox(),
onChanged: (String newValue) {
setState(() {
obraServicoDropDown = newValue;
print(obraServicoDropDown);
});
},
items: <String>['', 'SERVICO1', 'SERVICO2', 'SERVICO3']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
);
}).toList(),
hint: Container(
child: Text(
" SERVIÇO:",
style: TextStyle(color: Colors.white, fontSize: 20),
textAlign: TextAlign.end,
),
),
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: new TextField(
style: TextStyle(color: Colors.white, fontSize: 20),
decoration: new InputDecoration(
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5.0)),
borderSide: BorderSide(color: Colors.white),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5.0)),
borderSide: BorderSide(color: Colors.white),
),
hintText: "Descrição *",
hintStyle: TextStyle(fontSize: 20.0, color: Colors.white),
),
controller: _tDescricaoObra,
),
),
if (showAlert)
Text(
"Preencha os campos",
style: TextStyle(fontSize: 20, color: Colors.red),
),
new FlatButton(
color: Colors.orange,
child: new Text(
"CADASTRAR",
style: TextStyle(color: Colors.white),
),
onPressed: () {
if (obraServicoDropDown == null || _tDescricaoObra.text.isEmpty) {
showAlert = true;
} else {
ServicoObra servico = new ServicoObra();
servico.servico = obraServicoDropDown;
servico.descricao = _tDescricaoObra.text;
setState(() {
servicos.add(servico);
});
obraServicoDropDown = null;
_tDescricaoObra.clear();
showAlert = false;
Navigator.pop(context);
}
},
),
]),
),
);
}
obraServicoDropDown
在哪里初始化?我怀疑 obraServicoDropDown
的初始化发生在 Stateful Widget 的 Widget 的 build
函数中。因此,即使在 setState
将其更改为正确的状态后,obraServicoDropDown
的重新初始化也会带回原始状态。
从 showDialog 调用 setState 会改变 widget 的状态,但它不会重建对话框,因为 Flutter 不会仅仅因为我们改变了调用对话框的 widget 的状态就认为对话框的状态会改变.
解决这个问题的方法是让对话框有状态;通过 StatefulBuilder 或作为 StatefulWidget。无论哪种情况,现在更改对话框中的下拉状态只会在对话框中更改它;所以我们还需要来自主小部件的回调来更改那里的状态。下面的演示片段。
class DialogDropdown extends StatefulWidget {
const DialogDropdown({Key? key}) : super(key: key);
@override
State<DialogDropdown> createState() => _DialogDropdownState();
}
class _DialogDropdownState extends State<DialogDropdown> {
String? _grade;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text("Dialog Dropdown"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
_grade ?? "Unknown",
style: Theme.of(context).textTheme.headline4,
),
const Text(
'Grade',
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
showDialog(
context: context,
builder: (context) => gradeDialog(),
);
},
tooltip: 'Change Grade',
child: const Icon(Icons.arrow_upward),
),
);
}
void _changeGrade(_newGrade) {
setState(
() {
_grade = _newGrade;
},
);
}
StatefulBuilder gradeDialog() {
return StatefulBuilder(
builder: (context, _setter) {
return Dialog(
child: Padding(
padding: const EdgeInsets.all(15),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(_grade ?? "Unknown"),
const SizedBox(height: 30),
DropdownButton<String>(
value: _grade,
onChanged: (String? _newGrade) {
_setter(
() {
_grade = _newGrade!;
},
);
_changeGrade(_newGrade);
},
items: ["A", "B"].map<DropdownMenuItem<String>>(
(String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
},
).toList(),
),
],
),
),
);
},
);
}
}
当我在 dropdownMenuItem 中更改所选项目时,我的对话框不会将其更改为我select编辑的内容。
我有一个下拉列表显示客户端可以 select,当我 select 其中一个 selected 项目没有显示在字段中时,提示保持那里。
它以“SERVIÇO:”开头,并在更改项目后保持原样。 变量获取值但在显示中没有变化。
Future<void> _addObraServico(BuildContext context) async {
return showDialog(
context: context,
child: new Dialog(
backgroundColor: blueSoftwar,
child: new Column(children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
child: Text(
"SERVIÇOS",
style: TextStyle(
fontSize: 20,
color: Colors.white,
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: new Theme(
data: Theme.of(context).copyWith(
canvasColor: orangeSoftwar,
),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black),
borderRadius: BorderRadius.all(Radius.circular(
5.0) // <--- border radius here
),
),
child: DropdownButton<String>(
isExpanded: true,
value: obraServicoDropDown,
icon: const Icon(
Icons.arrow_downward,
color: Colors.white,
),
style: const TextStyle(color: Colors.white),
underline: SizedBox(),
onChanged: (String newValue) {
setState(() {
obraServicoDropDown = newValue;
print(obraServicoDropDown);
});
},
items: <String>['', 'SERVICO1', 'SERVICO2', 'SERVICO3']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
);
}).toList(),
hint: Container(
child: Text(
" SERVIÇO:",
style: TextStyle(color: Colors.white, fontSize: 20),
textAlign: TextAlign.end,
),
),
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: new TextField(
style: TextStyle(color: Colors.white, fontSize: 20),
decoration: new InputDecoration(
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5.0)),
borderSide: BorderSide(color: Colors.white),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5.0)),
borderSide: BorderSide(color: Colors.white),
),
hintText: "Descrição *",
hintStyle: TextStyle(fontSize: 20.0, color: Colors.white),
),
controller: _tDescricaoObra,
),
),
if (showAlert)
Text(
"Preencha os campos",
style: TextStyle(fontSize: 20, color: Colors.red),
),
new FlatButton(
color: Colors.orange,
child: new Text(
"CADASTRAR",
style: TextStyle(color: Colors.white),
),
onPressed: () {
if (obraServicoDropDown == null || _tDescricaoObra.text.isEmpty) {
showAlert = true;
} else {
ServicoObra servico = new ServicoObra();
servico.servico = obraServicoDropDown;
servico.descricao = _tDescricaoObra.text;
setState(() {
servicos.add(servico);
});
obraServicoDropDown = null;
_tDescricaoObra.clear();
showAlert = false;
Navigator.pop(context);
}
},
),
]),
),
);
}
obraServicoDropDown
在哪里初始化?我怀疑 obraServicoDropDown
的初始化发生在 Stateful Widget 的 Widget 的 build
函数中。因此,即使在 setState
将其更改为正确的状态后,obraServicoDropDown
的重新初始化也会带回原始状态。
从 showDialog 调用 setState 会改变 widget 的状态,但它不会重建对话框,因为 Flutter 不会仅仅因为我们改变了调用对话框的 widget 的状态就认为对话框的状态会改变.
解决这个问题的方法是让对话框有状态;通过 StatefulBuilder 或作为 StatefulWidget。无论哪种情况,现在更改对话框中的下拉状态只会在对话框中更改它;所以我们还需要来自主小部件的回调来更改那里的状态。下面的演示片段。
class DialogDropdown extends StatefulWidget {
const DialogDropdown({Key? key}) : super(key: key);
@override
State<DialogDropdown> createState() => _DialogDropdownState();
}
class _DialogDropdownState extends State<DialogDropdown> {
String? _grade;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text("Dialog Dropdown"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
_grade ?? "Unknown",
style: Theme.of(context).textTheme.headline4,
),
const Text(
'Grade',
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
showDialog(
context: context,
builder: (context) => gradeDialog(),
);
},
tooltip: 'Change Grade',
child: const Icon(Icons.arrow_upward),
),
);
}
void _changeGrade(_newGrade) {
setState(
() {
_grade = _newGrade;
},
);
}
StatefulBuilder gradeDialog() {
return StatefulBuilder(
builder: (context, _setter) {
return Dialog(
child: Padding(
padding: const EdgeInsets.all(15),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(_grade ?? "Unknown"),
const SizedBox(height: 30),
DropdownButton<String>(
value: _grade,
onChanged: (String? _newGrade) {
_setter(
() {
_grade = _newGrade!;
},
);
_changeGrade(_newGrade);
},
items: ["A", "B"].map<DropdownMenuItem<String>>(
(String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
},
).toList(),
),
],
),
),
);
},
);
}
}