【问题标题】:Open flutter dialog after navigation导航后打开颤振对话框
【发布时间】:2018-11-21 04:39:26
【问题描述】:

我调用 Navigator pushReplacement 在我的 Flutter 应用程序中显示一个新视图,并希望立即弹出一个简单的对话框来向用户介绍该页面。 (我希望用户能够在后台看到新视图)

如果我在小部件的 build 方法中调用 showDialog,然后从 build 方法返回一个小部件(脚手架),我会收到错误消息,指出颤动已经在绘制小部件。我希望我需要监听构建完成事件,然后调用 showDialog。

非常感谢有关如何做到这一点的指导。

【问题讨论】:

    标签: flutter


    【解决方案1】:

    您可以从“initState()”内部调用对话框,在第一帧绘制完成后延迟其外观。

      @override
      void initState() {
        super.initState();
        WidgetsBinding.instance.addPostFrameCallback((_) async {
          await showDialog<String>(
            context: context,
            builder: (BuildContext context) => new AlertDialog(
                  title: new Text("title"),
                  content: new Text("Message"),
                  actions: <Widget>[
                    new FlatButton(
                      child: new Text("OK"),
                      onPressed: () {
                        Navigator.of(context).pop();
                      },
                    ),
                  ],
                ),
          );
        });
      }
    

    context 变量始终在 State 类中可用。它指向这个小部件的RenderObject。问题在于initState() 中的上下文尚未创建,因此您必须在第一帧布局后推迟其使用。然后就可以使用了。

    【讨论】:

    • 你是如何获得 initState() 中的上下文的?
    • 上下文变量始终在 State 类中可用。它指向这个 Widget 的 RenderObject。问题是在 initState() 中尚未创建上下文,因此您必须在布置第一帧后推迟其使用。然后就可以使用了。
    • 是否可以使用无状态小部件实现相同的功能?
    【解决方案2】:

    另一种方法是使用Timer.run(...)

    @override
    void initState() {
      super.initState();
    
      // simply use this
      Timer.run(() {
        showDialog(
          context: context,
          builder: (_) => AlertDialog(title: Text("Dialog title")),
        );
      });
    }
    

    【讨论】:

      【解决方案3】:

      如果有人根据小部件值更新显示对话框的解决方案。

      例如,让用户知道他们尝试查看的屏幕已被删除。

      if (xxx.timestamps.deleted == null) {
        return DetailView(xxx: xxx);
      } else {
        return FutureBuilder(
          future: Future.delayed(
            Duration.zero,
            () => showDialog(
                context: context,
                builder: (_) => ActionDialog(
                    title: Text('xxx Deleted'),
                    content: Text('xxx deleted'),
                    confirmActions: [DialogConfirm.Ok])).then(
              (value) => Navigator.pop(context),
            ),
          ),
          builder: (context, _) => DetailView(xxx: xxx),
        );
      }
      

      感谢https://stackoverflow.com/a/64017240/2641128

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-07-14
        • 2022-11-11
        • 2021-11-24
        • 2019-09-02
        • 2020-06-02
        • 2020-05-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多