Flutter 如何在颤振中刷新AlertDialog?

Flutter 如何在颤振中刷新AlertDialog?,flutter,flutter-layout,flutter-alertdialog,Flutter,Flutter Layout,Flutter Alertdialog,目前,我有一个带有图标按钮的警报对话框。用户可以点击图标按钮,每次点击我有两种颜色。问题是我需要关闭AlertDialog并重新打开以查看颜色图标的状态更改。我想在用户单击图标按钮时立即更改其颜色 代码如下: bool pressphone = false; //.... new IconButton( icon: new Icon(Icons.phone), color: pressphone ? Colors.grey : Colors.green, onPressed:

目前,我有一个带有
图标按钮的
警报对话框
。用户可以点击图标按钮,每次点击我有两种颜色。问题是我需要关闭AlertDialog并重新打开以查看颜色图标的状态更改。我想在用户单击图标按钮时立即更改其颜色

代码如下:

bool pressphone = false;
//....
new IconButton(
   icon: new Icon(Icons.phone),
   color: pressphone ? Colors.grey : Colors.green,
   onPressed: () => setState(() => pressphone = !pressphone),
),

这是因为您需要将您的
AlertDialog
放在它自己的
StatefulWidget
中,并将所有状态操作逻辑移到颜色上

更新:

void main()=>runApp(MaterialApp(home:home());
类Home扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:中(
孩子:升起按钮(
子项:文本(“打开对话框”),
已按下:(){
显示对话框(
上下文:上下文,
建筑商:(){
返回MyDialog();
});
},
)));
}
}
类MyDialog扩展了StatefulWidget{
@凌驾
_MyDialogState createState()=>new_MyDialogState();
}
类_MyDialogState扩展了状态{
颜色_c=Colors.redAccent;
@凌驾
小部件构建(构建上下文){
返回警报对话框(
内容:容器(
颜色:c,
身高:20.0,
宽度:20.0,
),
行动:[
扁平按钮(
子项:文本('Switch'),
按下时:()=>设置状态(){
_c==Colors.redAccent
?_c=Colors.blueAccent
:_c=Colors.redAccent;
}))
],
);
}
}

使用StatefulBuilder在对话框内部使用setState,并仅在对话框内部更新小部件

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"),
            ),
          ],
        );
      },
    );
  },
);
showDialog(
上下文:上下文,
生成器:(上下文){
String contentText=“对话框的内容”;
返回状态生成器(
生成器:(上下文,设置状态){
返回警报对话框(
标题:文本(“对话框标题”),
内容:文本(contentText),
行动:[
扁平按钮(
onPressed:()=>Navigator.pop(上下文),
子项:文本(“取消”),
),
扁平按钮(
已按下:(){
设置状态(){
contentText=“更改了对话框的内容”;
});
},
子项:文本(“更改”),
),
],
);
},
);
},
);

当前用于检索我使用的对话框的值

showDialog().then((val){
setState (() {}); 
print (val);
});
范例 第一屏

    onPressed: () { 
    showDialog(
       context: context,
       barrierDismissible: false,
       builder: (context) {
         return AddDespesa();
       }).then((val) {
         setState(() {});
         print(val);
        }
    );
   }
第二屏

AlertDialog(
    title: Text("Sucesso!"),
    content: Text("Gasto resgristrado com sucesso"),
    actions: <Widget>[
    FlatButton(
      child: Text("OK"),
      onPressed: () {
         Navigator.pop(context, true);
      },
     ),
   ],
 );
警报对话框(
标题:文本(“Sucesso!”),
内容:文本(“Gasto resgristrado com Successo”),
行动:[
扁平按钮(
孩子:文本(“OK”),
已按下:(){
pop(上下文,true);
},
),
],
);

将打印为true,

文档建议您在AlertDialog的
内容
部分使用
StatefulBuilder
。即使是最新版本,实际上也有一个带有对话框的示例

它所做的是为您提供一个新的上下文和setState函数,以便在需要时重建

文档中的示例代码:

showDialog(
  context: context,
  builder: (BuildContext context) {

    int selectedRadio = 0; // Declare your variable outside the builder

    return AlertDialog( 
      content: StatefulBuilder(  // You need this, notice the parameters below:
        builder: (BuildContext context, StateSetter setState) {
          return Column(  // Then, the content of your dialog.
            mainAxisSize: MainAxisSize.min,
            children: List<Widget>.generate(4, (int index) {
              return Radio<int>(
                value: index,
                groupValue: selectedRadio,
                onChanged: (int value) {
                  // Whenever you need, call setState on your variable
                  setState(() => selectedRadio = value);
                },
              );
            }),
          );
        },
      ),
    );
  },
);
showDialog(
上下文:上下文,
生成器:(BuildContext上下文){
int selectedRadio=0;//在生成器外部声明变量
返回警报对话框(
content:StatefulBuilder(//如果需要,请注意以下参数:
生成器:(BuildContext上下文,StateSetter setState){
返回列(//然后是对话框的内容。
mainAxisSize:mainAxisSize.min,
子项:List.generate(4,(int索引){
回程收音机(
值:索引,
groupValue:selectedRadio,
onChanged:(int值){
//无论何时需要,对变量调用setState
设置状态(()=>selectedRadio=value);
},
);
}),
);
},
),
);
},
);
正如我所提到的,这是报纸上说的:

[…]生成器返回的小部件与位置不共享上下文 该showDialog最初是从调用的使用StatefulBuilder或 自定义StatefulWidget(如果对话框需要动态更新)


首先,您需要使用
StatefulBuilder
。然后我设置
\u setState
变量,该变量甚至可以在
StatefulBuilder
外部使用,以设置新状态

StateSetter _setState;
String _demoText = "test";

showDialog(
  context: context,
  builder: (BuildContext context) {

    return AlertDialog( 
      content: StatefulBuilder(  // You need this, notice the parameters below:
        builder: (BuildContext context, StateSetter setState) {
          _setState = setState;
          return Text(_demoText);
        },
      ),
    );
  },
);
_setState的使用方法与setState方法相同。例如:

_setState(() {
    _demoText = "new test text";
});

谢谢,我试图创建另一个stful小部件类,但是当我按下按钮调用我的widet时,我什么都没有。通常,当我调用alertdialog stfull小部件时,它会返回@override小部件构建(BuildContext上下文){return new alertdialog(内容:new Container….我试图扩展它以更改“ok”的启用/禁用状态对话框的操作按钮。但我还没有取得任何成功。有什么建议吗?这是最好的方法!完美的解决方案,用于创建有状态的AlertDialog。应该是公认的答案,因为这为代码重构提供了更多选项,而不是嵌套的代码块。感谢您提供了清晰的答案。50+这是正确的答案,我从没想过你可以“subClass\subOverload”[setState]live Saviour也不为我工作。有人能解释为什么它对某些人不起作用吗?我在Dart 2.8.1和FLART 1.19.0-0.0.pre上,它在WEB上按预期工作,谢谢:)@MutluSimsek当您试图设置在StatefulBuilder/StatefulWidgetHanks外部声明的变量时,它不起作用。它对我起作用。但是如果我从外部单独方法在有状态生成器中添加任何子项,它就不起作用。然后,如果我直接在有状态生成器中添加子项,它就会起作用。在有状态生成器工作。如果它在有状态生成器之外,那么我
_setState(() {
    _demoText = "new test text";
});