查找停用的小部件的祖先是不安全的

我是新在扑动,我正在尝试接收数据与对话框。 当单击 textField 时,图像2的错误显示..。

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

这是我的原则。

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):
161700 次浏览

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.

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

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

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

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

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

use this:

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

instead of

Navigator.of(context).pop();

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.

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

declare dialog and set in initState

  late Dialog dialog;


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


dialog = Dialog(
...
);
}

first : declare a FormKey.

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

second : add the FormKey to your Form widget.

Form(


key:myFormKey,


child:child


)

In my case i was calling

setState(() {
Navigator.pop(context);
});

removing application from emulator and run below commands

flutter clean
flutter pub get

works for me

before calling a dialog when a page is just loading, call it by adding SchedulerBinding to it, call it like this

SchedulerBinding.instance?.addPostFrameCallback((_) => showDialog( context: context, barrierDismissible: false, builder: (context) { return dialogBox(context, "Fetching account data", 'Profile page', DialogType.processing, function: () {}, dismissText: "", ); }));

Though you got desired answer, just for better clarification for others I put my opinion here.

It is happend due to context mismatch issue. Your passing context to Navigator.of(context).pop() is not matching with your MainApp BuildContext.

Solution : There has 2 way

  1. U can use Global key
  2. pass actual context to your Navigator

Below link I already mentioned how to solve this by passing actual context

https://stackoverflow.com/a/73543251/6109034