1

I have two stacked Scaffolds, a parent and a child. On button press, both Scaffolds show a popup each from their own context. But no matter what, Navigator.pop always dismiss the top most popup, ignoring the passed context.

class StateTest extends State<ScreenTest>{

  BuildContext parent, child;

  @override
  Widget build(BuildContext context) => Scaffold(
    drawer : Drawer(child: Container()),
    body: Builder(builder : (BuildContext context){
      this.parent = context;
      return Scaffold(
        body: Builder(builder : (BuildContext context){
          this.child = context;
        }),
        floatingActionButton: FloatingActionButton(
          onPressed: (){
            showDialog(context: parent, child: Center(child: Text('PARENT')));
            showDialog(context: child, child: Center(child: Text('CHILD')));
            Timer(Duration(seconds: 1), () => Navigator.of(parent).pop());
          }
        ),
      );
    })
  );
}

I just want to dismiss popup from specific context.

stackunderflow
  • 1,492
  • 1
  • 23
  • 53
  • 1
    You could try setting the rootNavigator parameter to true for the pop of the parent. I haven't tested it though. See https://stackoverflow.com/questions/55548153/flutter-navigator-ofcontext-pop-vs-navigator-popcontext-difference – GrahamD Jan 05 '20 at 07:20
  • tried it. not working either – stackunderflow Jan 05 '20 at 07:27
  • 1
    Can I ask why you are nesting scaffolds? It is not generally recommended. See:https://api.flutter.dev/flutter/material/Scaffold-class.html in the trouble shooting section. – GrahamD Jan 05 '20 at 07:34
  • actually this is my original problem. i thought i could solve it by stacking the scaffolds but not. let me try separate their states to see how it's going https://stackoverflow.com/questions/59590939/flutter-how-to-dismiss-a-showdialog-widget-in-the-middle – stackunderflow Jan 05 '20 at 07:40
  • If I read that correctly, A and B run concurrently, both show a busy progress indicator but only B shows the alert dialogue. Is that right? If so, then why don't you wait for both to finish before showing the alert dialogue. Or you can set a 'busy' bool in both processes and only clear it when B finishes in a call to setState() {}. Then show your busy progress indicator until 'busy' is false. – GrahamD Jan 05 '20 at 09:23
  • actually it is an example. the idea is to keep the busy circle always at the top. i thought with stacked `Scaffold`s, busy circle from outer `Scaffold` will always overlay everything from inner `Scaffold`, like it does to other `Scaffold`'s components. that is before i came up with this question – stackunderflow Jan 05 '20 at 13:29
  • 1
    Ok so to display the spinner on top use Stack() and make the circular progress indicator one of the child widgets. – GrahamD Jan 05 '20 at 14:00

1 Answers1

3

Navigator.of(context) gets the closest Navigator parent widget.

Both parent and child context refer to the same navigator so both dialogs are pushed to the same navigator and the last dialog is the one popped

The way to do it is adding a new navigator:

  • The dialog you want to show closer to the user is has to be the farthest navigator. In our case the root navigator

  • The dialog that will be display between the scaffold and the other dialog should be pushes from the new created navigator

See online demo


class StateTest extends State<ScreenTest>{

  @override
  Widget build(BuildContext context) => 
    Navigator(
         onGenerateRoute: _getRoute
  );

  Route _getRoute(RouteSettings settings) {
    switch (settings.name){
      case '/':
        return MaterialPageRoute(
      settings: settings,
      builder: (BuildContext context) {
          return Scaffold(body: Container(), floatingActionButton: FloatingActionButton(
          onPressed: (){
            showDialog(context: context, child: Center(child: Text('PARENT')), useRootNavigator: false);
            showDialog(context: context, child: Center(child: Text('CHILD')), );
            Timer(Duration(seconds: 1), () => Navigator.of(context).pop());
          }
        ));
        });
      default:
        return null;
    }

  }

}

A drawing explaining the widget tree

example

jamesblasco
  • 1,744
  • 1
  • 9
  • 25