71

我是 Flutter 的新手,我正在尝试使用 Dialog 接收数据。当在 textField 中单击时,会出现 image2 的错误...

布局的图像 错误的图像

show(BuildContext context){

    var dialog = Dialog(
      child: Container(
        margin: EdgeInsets.all(8.0),
        child: Form(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              TextFormField(
                decoration: InputDecoration(
                    labelText: "Insira o número de telefone",
                    border: OutlineInputBorder(
                        borderRadius: BorderRadius.all(Radius.circular(2.0)))),
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: <Widget>[
                  FlatButton(
                      onPressed: () {
                        Navigator.of(context).pop();
                      },
                      child: Text("Cancelar")),
                  FlatButton(
                      onPressed: () {
                        Navigator.of(context).pop();
                      },
                      child: Text("Aceitar"))
                ],
              )
            ],
          ),
        ),
      ),
    );

    showDialog(context: context,builder: (context){
      return dialog;
    });
  }

这是我的代码。

I/flutter (31032): Looking up a deactivated widget's ancestor is unsafe.
I/flutter (31032): At this point the state of the widget's element tree is no longer stable. To safely refer to a
I/flutter (31032): widget's ancestor in its dispose() method, save a reference to the ancestor by calling
I/flutter (31032): inheritFromWidgetOfExactType() in the widget's didChangeDependencies() method.
I/flutter (31032): 
4

11 回答 11

61

声明一个全局变量

    final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

然后在您的小部件构建的脚手架上注册密钥,例如

    @override
    Widget build(BuildContext context) {
     return Scaffold(
       key: _scaffoldKey,
       ...

然后在对话框中

show(BuildContext context){

var dialog = Dialog(
  child: Container(
    margin: EdgeInsets.all(8.0),
    child: Form(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          TextFormField(
            decoration: InputDecoration(
                labelText: "Insira o número de telefone",
                border: OutlineInputBorder(
                    borderRadius: BorderRadius.all(Radius.circular(2.0)))),
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.end,
            children: <Widget>[
              FlatButton(
                  onPressed: () {
                    Navigator.of(context).pop();
                  },
                  child: Text("Cancelar")),
              FlatButton(
                  onPressed: () {
                    Navigator.of(context).pop();
                  },
                  child: Text("Aceitar"))
            ],
          )
        ],
      ),
    ),
  ),
);

将该脚手架上下文传递给 showDialog 方法

showDialog(context: _scaffoldKey.currentContext ,builder: (context){
  return dialog;
 });
}
于 2019-09-12T14:53:30.593 回答
46

尝试这个

为对话框提供不同的上下文名称

 showDialog(context: context,builder: (dialogContex){
              return Dialog(
                child: Container(
                  margin: EdgeInsets.all(8.0),
                  child: Form(
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      children: <Widget>[
                        TextFormField(
                          decoration: InputDecoration(
                              labelText: "Insira o número de telefone",
                              border: OutlineInputBorder(
                                  borderRadius: BorderRadius.all(Radius.circular(2.0)))),
                        ),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.end,
                          children: <Widget>[
                            FlatButton(
                                onPressed: () {
                                  Navigator.of(dialogContex).pop();
                                },
                                child: Text("Cancelar")),
                            FlatButton(
                                onPressed: () {
                                  Navigator.of(context).pop();
                                },
                                child: Text("Aceitar"))
                          ],
                        )
                      ],
                    ),
                  ),
                ),
              );
            });
于 2019-08-28T13:50:01.777 回答
24

我在尝试打开对话框时遇到了同样的错误,我在这里找到了解决方案:github flutter issues。具体来说,我遵循了发帖人的建议,即创建一个GlobalKey并将其与Scaffold小部件相关联,并在创建对话框时使用该键的上下文。就我而言,我有一个全局可访问的对象,其中包含GlobalKey

MyGlobals myGlobals = MyGlobals();
class MyGlobals {
  GlobalKey _scaffoldKey;
  MyGlobals() {
    _scaffoldKey = GlobalKey();
  }
  GlobalKey get scaffoldKey => _scaffoldKey;
}

Scaffold小部件构造函数调用中:

Scaffold(
  appBar: ...,
  body: ...,
  drawer: ...,
  key: myGlobals.scaffoldKey,
)

showDialog通话中:

showDialog<String>(
  barrierDismissible: ...,
  builder: ...,
  context: myGlobals.scaffoldKey.currentContext,
);
于 2019-05-12T22:00:24.410 回答
17

您正在尝试访问可能不可用的上下文。发生这种情况是因为您已将您分配Dialog给 a var,然后使用不同的上下文(来自对话框构建器的上下文)。

要么直接在构建器中创建对话框,return要么将其作为方法而不是返回 aDialog并将其传递给 BuildContext参数。

Widget myDialog(BuildContext context) => Dialog(/*your dialog here*/);

这也是一种更方便的 Flutter 实践。您应该使用返回小部件的方法,而不是将其分配给变量。

于 2019-02-10T15:13:28.593 回答
10

用这个:

Navigator.of(context,rootNavigator: true).pop();

代替

Navigator.of(context).pop();
于 2021-03-19T04:38:43.377 回答
8

当您从上下文中弹出并尝试在您弹出的上下文中打开新内容时,可能会发生这种情况。

()async{
    Navigator.of(context).pop();
    _alertPopUp(); // shows a dialog
    // might do some work after
}

如果在当前上下文中创建了警报对话框,则会引发错误,因为上下文不再存在

于 2021-01-03T15:15:00.817 回答
0

尝试这个:

    Future<AlertDialog> myDialog(BuildContext context) {
    return showDialog<AlertDialog>(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          content: Container(
            margin: EdgeInsets.all(8.0),
            child: Form(
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  TextFormField(
                    decoration: InputDecoration(
                        labelText: "Insira o número de telefone",
                        border: OutlineInputBorder(
                            borderRadius:
                                BorderRadius.all(Radius.circular(2.0)))),
                  ),
                ],
              ),
            ),
          ),
          actions: <Widget>[
            FlatButton(
                onPressed: () {
                  Navigator.of(context).pop();
                },
                child: Text("Cancelar")),
            FlatButton(
                onPressed: () {
                  Navigator.of(context).pop();
                },
                child: Text("Aceitar"))
          ],
        );
      },
    );
  }
于 2019-02-11T08:37:22.167 回答
0

我的问题是我使用热重载很长一段时间,我认为在某些时候一切都搞砸了,正常运行应用程序解决了这个问题。

于 2021-09-24T00:14:14.853 回答
0
You are setting the state after the widget is deactivated. Try adding this before setState to set it only if the widget is mounted:

if(mounted) setState(() => ...);


Alternatively, you can override the setState method to make all the setState calls safe:

@override
void setState(fn) {
    if(mounted) super.setState(fn);
}
于 2021-12-21T04:04:28.747 回答
0

声明对话框并设置initState

  late Dialog dialog;

  @override
  void initState() {
    super.initState();

    dialog = Dialog(
      ...
    );
  }
于 2022-02-08T11:30:28.030 回答
-2

我只是通过使用 Builder 小部件包装 showDialog 解决了这个问题,尽管对我来说错误来自流构建器我只是用构建器小部件包装流构建器并从流构建器中调用的流中删除通知侦听器,但在您的情况下,使用 Builder 小部件包装 showDialog,它将使用来自构建器的上下文,问题已解决

于 2021-12-08T21:14:53.333 回答