81

I am new in Flutter and I am trying receive data with a Dialog. When a click in textField the error of image2 appear...

Layout's Image Error's Image

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;
    });
  }

This is my code.

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): 
Paresh Mangukiya
  • 37,512
  • 17
  • 201
  • 182
a2x
  • 811
  • 1
  • 5
  • 4

13 Answers13

72

Declare a global variable

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

then register the key on your widget build's scaffold eg

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

then on the dialog

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

Pass that scaffold context to the showDialog method

showDialog(context: _scaffoldKey.currentContext ,builder: (context){
  return dialog;
 });
}
Felix Runye
  • 1,417
  • 16
  • 17
  • 1
    thanks! this helped me with one of my dialogs, but i have another page which whenever loggs in successfully i pop using ```navigator.of(context)..pop()..pop()..pop("yes")``` but when dialog is shown i face this error, i used a scaffold key and also the builder. – Mahdi-Jafaree Oct 18 '20 at 06:19
  • This works for me having a big calling project.. which has multiple roles types .. passing scaffold.currentContext! has solved the issues as I was using the function for multiple roles of pages. Kudos to solution !! – neon97 Aug 06 '21 at 11:42
  • 3
    Thanks for the answer! Can you explain why this works a bit? – batuhankrbb Aug 17 '21 at 03:54
  • ``Navigator.of(_scaffoldKey.currentContext!).pop();`` to close dialog – Mod May 19 '22 at 03:52
50

Try This

Give different context name for dialog

 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"))
                          ],
                        )
                      ],
                    ),
                  ),
                ),
              );
            });
Savad
  • 1,263
  • 11
  • 17
25

I got the same error when attempting to open a dialog and I found a solution here: github flutter issues. Specifically, I followed the poster's recommendation, which was to create a GlobalKey and associate it with the Scaffold widget, and use the context from that key when creating the dialog. In my case, I have a globally accessible object which holds the GlobalKey:

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

In the Scaffold widget constructor call:

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

And in the showDialog call:

showDialog<String>(
  barrierDismissible: ...,
  builder: ...,
  context: myGlobals.scaffoldKey.currentContext,
);
Andy King
  • 1,562
  • 1
  • 20
  • 28
  • @ajs.sonawane Do you mean that it doesn't work when you create a dialog from within a dialog, or it doesn't work when you try to use it a second time with the same dialog, or that it doesn't work if you use it for one dialog, close that dialog, and then open a different dialog? – Andy King Jul 11 '20 at 17:17
  • 2
    nope, calling dialog then popping it and then calling it again – ajs.sonawane Jul 11 '20 at 18:03
  • @ajs.sonawane It seems to be working for my situation ... perhaps you will need to post a new question. Sorry. – Andy King Jul 12 '20 at 06:19
17

You’re trying to access a context that isn’t probably available. That happens because you’ve assigned your Dialog to a var and afterwards use a different context (the one from your dialog builder).

Either create your dialog directly after your return in the builder or make it a method instead that returns a Dialog and pass it a BuildContext parameter.

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

This is also a more convenient Flutter practice. You should use methods that return widgets instead of assigning it to variables.

Miguel Ruivo
  • 13,004
  • 5
  • 46
  • 78
  • You need to provide more code context/info then. At first glance that's what it seems, because when you are popping the `Dialog` you may be referring to an invalid widget context. – Miguel Ruivo Feb 10 '19 at 23:01
  • 1
    This is **not** a convenient flutter practice. See https://stackoverflow.com/a/53234826/10122791 – Augustin R Nov 25 '19 at 09:00
11

use this:

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

instead of

Navigator.of(context).pop();
biruk IS
  • 1,029
  • 6
  • 11
  • 5
    Can you elaborate a bit on this? Why / in which cases is the latter preferable? – dgilperez Apr 09 '21 at 13:05
  • For Explaination please visit : https://stackoverflow.com/questions/60349741/what-is-the-use-of-rootnavigator-in-navigator-ofcontext-rootnavigator-true – Sayed Muhammad Idrees Nov 16 '21 at 18:59
  • This will not necessarily help. If your context is outdated, this might still fail, as even with the `rootNavigator: true` part you are still accessing a `BuildContext` that is no longer viable. Also: you might discover unwanted navigation behaviour, e.g., when you use tab bars. – Matthias Schicker May 27 '22 at 12:34
8

This might happen while you are popping from the context and trying to open new content on the context you are popping.

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

if alert dialog is created on current context then it throws an error because context doesn't exist anymore

Pang
  • 9,073
  • 146
  • 84
  • 117
enumerator
  • 147
  • 3
  • 2
4

My problem was that I was using hot reload for pretty long time, I think at some point everything got messed up, doing a normal run of the app fixed the problem.

Ray Rojas
  • 101
  • 1
  • 8
  • Seems like this is the answer which worked i dont know if flutter could be notified of this issue – ditso k May 14 '22 at 11:36
0

Try this:

    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"))
          ],
        );
      },
    );
  }
Fellipe Malta
  • 2,244
  • 1
  • 6
  • 11
0

declare dialog and set in initState

  late Dialog dialog;

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

    dialog = Dialog(
      ...
    );
  }
Linar
  • 468
  • 3
  • 7
0

first : declare a FormKey.

 GlobalKey<FormState>myFormKey=GlobalKey<FormState>();

second : add the FormKey to your Form widget.

Form( 

 key:myFormKey,

 child:child

 )
0

In my case i was calling

setState(() {
   Navigator.pop(context);
});
Ravindra S. Patil
  • 6,553
  • 2
  • 6
  • 23
Muhammad Kashif
  • 111
  • 1
  • 5
0

removing application from emulator and run below commands

flutter clean
flutter pub get 

works for me

mayfall
  • 21
  • 4
-2

I simply solved this by wrapping the showDialog with a Builder widget, though for me the error came from a stream builder I simply wrap the stream builder with a builder widget and the remove the notify listeners from the a stream am calling in the stream builder, but in your case wrap the showDialog with a Builder widget and it will use the context from the builder, problem solved