Как обновить AlertDialog во флаттере?
В настоящее время у меня есть AlertDialog
с IconButton
. Пользователь может нажать на иконку, у меня есть два цвета для каждого клика. Проблема в том, что мне нужно закрыть AlertDialog и снова открыть, чтобы увидеть изменение состояния значка цвета. Я хочу немедленно изменить цвет IconButton, когда пользователь щелкнет по нему.
Вот код:
bool pressphone = false;
//....
new IconButton(
icon: new Icon(Icons.phone),
color: pressphone ? Colors.grey : Colors.green,
onPressed: () => setState(() => pressphone = !pressphone),
),
Ответы
Ответ 1
Это потому, что вам нужно поместить свой AlertDialog
в его собственный StatefulWidget
и переместить всю логику манипуляции состояниями на цвет там.
Обновление:
void main() => runApp(MaterialApp(home: Home()));
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RaisedButton(
child: Text('Open Dialog'),
onPressed: () {
showDialog(
context: context,
builder: (_) {
return MyDialog();
});
},
)));
}
}
class MyDialog extends StatefulWidget {
@override
_MyDialogState createState() => new _MyDialogState();
}
class _MyDialogState extends State<MyDialog> {
Color _c = Colors.redAccent;
@override
Widget build(BuildContext context) {
return AlertDialog(
content: Container(
color: _c,
height: 20.0,
width: 20.0,
),
actions: <Widget>[
FlatButton(
child: Text('Switch'),
onPressed: () => setState(() {
_c == Colors.redAccent
? _c = Colors.blueAccent
: _c = Colors.redAccent;
}))
],
);
}
}
Ответ 2
showDialog(
context: context,
builder: (context) {
String contentText = "Content of Dialog";
return StatefulBuilder(
builder: (context, setState) {
return AlertDialog(
title: Text("Title of Dialog"),
content: Text(contentText),
actions: <Widget>[
FlatButton(
onPressed: () => Navigator.pop(context),
child: Text("Cancel"),
),
FlatButton(
onPressed: () {
setState(() {
contentText = "Changed Content of Dialog";
});
},
child: Text("Change"),
),
],
);
},
);
},
);
Ответ 3
В настоящее время для получения значения Dialog я использую
showDialog().then((val){
setState (() {});
print (val);
});
Пример
1-й экран
onPressed: () {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) {
return AddDespesa();
}).then((val) {
setState(() {});
print(val);
}
);
}
2-й экран
AlertDialog(
title: Text("Sucesso!"),
content: Text("Gasto resgristrado com sucesso"),
actions: <Widget>[
FlatButton(
child: Text("OK"),
onPressed: () {
Navigator.pop(context, true);
},
),
],
);
Будет напечатано верно,
Ответ 4
Документы предполагают, что вы используете StatefulBuilder
в разделе content
AlertDialog. Даже у StatefulBuilder docs действительно есть пример с диалоговым окном.
Что он делает, так это предоставляет вам новый контекст и функцию setState для восстановления при необходимости.
Пример кода из документации:
showDialog<void>(
context: context,
builder: (BuildContext context) {
int selectedRadio = 0;
return AlertDialog(
content: StatefulBuilder( // You need this, notice the parameters below:
builder: (BuildContext context, StateSetter setState) {
return Column(
mainAxisSize: MainAxisSize.min,
children: List<Widget>.generate(4, (int index) {
return Radio<int>(
value: index,
groupValue: selectedRadio,
onChanged: (int value) {
setState(() => selectedRadio = value);
},
);
}),
);
},
),
);
},
);
И, как я уже говорил, об этом говорится в документах showDialog:
[...] Возвращенный компоновщиком виджет не имеет общего контекста с местоположением этот showDialog изначально вызывается из. Используйте StatefulBuilder или пользовательский StatefulWidget, если диалог должен обновляться динамически.