如何在 Flutter 中刷新 AlertDialog?

Posted

技术标签:

【中文标题】如何在 Flutter 中刷新 AlertDialog?【英文标题】:How to refresh an AlertDialog in Flutter? 【发布时间】:2019-01-28 10:39:55 【问题描述】:

目前,我有一个AlertDialog 和一个IconButton。用户可以点击 IconButton,每次点击我都有两种颜色。问题是我需要关闭 AlertDialog 并重新打开才能看到颜色图标的状态变化。我想在用户单击时立即更改 IconButton 颜色。

代码如下:

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

【问题讨论】:

【参考方案1】:

如果您通过 View Models 将数据与 UI 分离并使用 Provider 包和 ChangeNotifier,则需要像这样在调用对话框的小部件中包含当前模型:

showDialog(context: context, builder: (dialog) 
              return ChangeNotifierProvider.value(
                  value: context.read<ViewModel>(),
                child: CustomStatefulDialogWidget(),
              );
            ,

请注意,可能有更简洁的方法可以做到这一点,但这对我有用。

关于Provider的其他信息:https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple

【讨论】:

【参考方案2】:

在 AlertDialog 的 content 部分中使用 StatefulBuilder。甚至StatefulBuilder docs 实际上也有一个带有对话框的示例。

它的作用是为您提供一个新的context,以及在需要时重建的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 docs 上所说的:

[...] 构建器返回的小部件不与位置共享上下文 该 showDialog 最初是从中调用的。 使用 StatefulBuilder 或 如果对话框需要动态更新,则自定义 StatefulWidget

【讨论】:

完美!卡在这上面好久了!【参考方案3】:

使用 StatefulBuilder 在 Dialog 内部使用 setState 并仅在其中更新 Widget。

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>[
            TextButton(
              onPressed: () => Navigator.pop(context),
              child: Text("Cancel"),
            ),
            TextButton(
              onPressed: () 
                setState(() 
                  contentText = "Changed Content of Dialog";
                );
              ,
              child: Text("Change"),
            ),
          ],
        );
      ,
    );
  ,
);

【讨论】:

这是正确答案,我从没想过你可以'subClass\subOverload' [setState] live saviour 也不适合我。有没有人可以解释为什么它对某些人不起作用? 我正在使用 Dart 2.8.1 和 Flutter 1.19.0-0.0.pre,它在 WEB 中按预期工作,谢谢 :) @MutluSimsek 当您尝试 setState 一个在 StatefulBuilder/StatefulWidget 之外声明的变量时,它不起作用 谢谢。它对我有用。但是,如果我从外部单独的方法在有状态的构建器中添加任何孩子,它就不起作用。然后,如果我直接在有状态的构建器中添加孩子,它就可以工作。更改有状态构建器中的变量是可行的。如果它在有状态构建器之外,则它不起作用。【参考方案4】:

首先你需要使用StatefulBuilder。然后我设置_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";
);

【讨论】:

这项工作非常适合我,这是我发现能够从对话框代码外部更新对话框内容的唯一方法。【参考方案5】:

目前要检索我使用的 Dialog 的值

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

将被打印出来,

【讨论】:

这并没有真正改变对话框的状态,因为对话框有自己的状态,使用常规的 setState 真的解决不了任何问题。【参考方案6】:

这是因为您需要将您的 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;
                ))
      ],
    );
  

【讨论】:

谢谢,我尝试创建另一个 stful 小部件类,但是当我按下按钮调用我的 Widet 时,我什么都没有。 Normaly 当我调用我的 alertdialog stfull 小部件时它返回这个 @override Widget build(BuildContext context) return new AlertDialog( content: new Container .... 我正在尝试扩展它以更改对话框的“确定”操作按钮的启用/禁用状态。但我还没有任何成功。有什么建议吗? 这是最好的方法! 完美的解决方案,用于创建有状态的 AlertDialog。应该是公认的答案,因为这为代码重构而不是嵌套代码块提供了更多选项。谢谢你的干净答案。 50+ 非常有用,谢谢

以上是关于如何在 Flutter 中刷新 AlertDialog?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 中刷新 AlertDialog?

Flutter中如何返回刷新上一页?

如何在 Flutter 上刷新 firebase 令牌?

如何在Flutter中刷新AlertDialog?

如何使用flutter,wordpress在我的应用程序中添加拉动刷新? [关闭]

如何在按钮单击 FLUTTER 上刷新列表小部件数据