123

I am new to flutter, I want to dismiss my dialog after the task completion. I've tried with:

Navigator.pop(context, true); 

But my screen is getting black and dialog is still up there. here is my dialog code.

Dialog _dialog = new Dialog(
  child: new Row(
    mainAxisSize: MainAsixSize.min, 
    children: <Widget> [
    new CircularProgressIndicator(), 
    new Text("Loading")]),     

); 
piet.t
  • 11,718
  • 21
  • 43
  • 52
Ammy Kang
  • 11,283
  • 21
  • 46
  • 68

11 Answers11

154

https://api.flutter.dev/flutter/material/showDialog.html says

The dialog route created by this method is pushed to the root navigator. If the application has multiple Navigator objects, it may be necessary to call Navigator.of(context, rootNavigator: true).pop(result) to close the dialog rather just Navigator.pop(context, result).

so I'd assume one of these two should do what you want.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 7
    what is 'result' here? – Ammy Kang Jun 04 '18 at 15:11
  • 6
    `result` is an optional argument that the `route` which called `showDialog` can receive. It's useful if for example your dialog select a value that the UI need to use. – Rémi Rousselet Jun 04 '18 at 15:12
  • 2
    Any value you want the `Future` returned from `showDialog()` complete with when you dismiss the dialog. – Günter Zöchbauer Jun 04 '18 at 15:12
  • Thanks @GünterZöchbauer, its working for real device but same is still there on Simulator. – Ammy Kang Jun 04 '18 at 15:23
  • Hard to tell if it works on the device. A wild guess would be `flutter clean`. What Flutter version are you using? – Günter Zöchbauer Jun 04 '18 at 15:25
  • 1
    0.3.2 sounds a bit outdated. What is actually the current state. " its working for real device" and "also not working for android device" seem contradicting. – Günter Zöchbauer Jun 04 '18 at 15:30
  • 2
    working for iOS device, but not for android device and simulator, let me try to upgrade flutter. and Thanks a lot @GünterZöchbauer – Ammy Kang Jun 04 '18 at 15:32
  • @GünterZöchbauer I have a login page as `initialRoute`, I need to call `Navigator.pop(context)` when login succeeds, and I also need to show a dialog during login, that means **I need to call `Navigator.pop(context)` twice**, otherwise, just dialog is dismissed, the login page is still there. It's kind of confused to have two `pop`, why not dialog.dismiss()? Thanks – Weiyi Jan 19 '19 at 06:30
  • 1
    you saved me from a minor headache – vanlooverenkoen May 31 '19 at 14:20
  • 1
    I cannot edit the link. The right one is [here](https://api.flutter.dev/flutter/material/showDialog.html) – AndreP Apr 21 '23 at 10:30
80

This code works for me:

  BuildContext dialogContext;
  showDialog(
    context: context,
    barrierDismissible: false,
    builder: (BuildContext context) {
      dialogContext = context;
      return Dialog(
        child: new Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            new CircularProgressIndicator(),
            new Text("Loading"),
          ],
        ),
      );
    },
  );

  await _longOperation();
  Navigator.pop(dialogContext);
live-love
  • 48,840
  • 22
  • 240
  • 204
  • 6
    this should be the accepted answer. Using the context that's not from the builder causes the screen to navigate pop instead of closing the dialog. – Axes Grinds Dec 28 '20 at 01:56
  • 1
    Agreed to @AxesGrinds – Saikat halder Jan 04 '21 at 17:16
  • What happens here if the user press back button while the _longOperation is still in progress? – Santi Iglesias Feb 14 '21 at 16:14
  • Awesome, this helped me with an edge case where the dialog won't dismiss using a basic `Navigator.of(context).pop()`. Thanks! – Toma Apr 01 '21 at 00:20
  • how to return something with this? Navigator.pop(dialogContext,variable)? – vontdeux Jul 14 '21 at 01:32
  • Agree with 'Axes Grinds'. This should be the accepted answer. – sigjak Sep 30 '21 at 16:28
  • 1
    This didn't work for me with a popup inside a CupertinoTabScaffold. The screen below would be dismissed, but the popup would stay (and clicking again throws an exception that the widget has no root). A CupertinoTabScaffold has multiple navigator objects, while the dialog is pushed to the root navigator. – Harmen Jan 02 '22 at 18:26
33

If you don't want to return any result after showDialog is closed, you can use

Navigator.pop(context);

If you want to pass result call

Navigator.pop(context, result);

Example:

showDialog(
    context: context,
    builder: (_) {
      return AlertDialog(
        title: Text('Wanna Exit?'),
        actions: [
          FlatButton(
            onPressed: () => Navigator.pop(context, false), // passing false
            child: Text('No'),
          ),
          FlatButton(
            onPressed: () => Navigator.pop(context, true), // passing true
            child: Text('Yes'),
          ),
        ],
      );
    }).then((exit) {
  if (exit == null) return;

  if (exit) {
    // user pressed Yes button
  } else {
    // user pressed No button
  }
});
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
20
//it work conrrectly
onPressed: () {
   Navigator.of(context, rootNavigator: true).pop();
},
Wai Yan Moung
  • 239
  • 2
  • 5
13

Generally Navigator.pop(context); works.

But If the application has multiple Navigator objects and dialogBox doesn't close, then try this

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

If you want to pass result call, try

Navigator.pop(context,result);

OR

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

Vicky Salunkhe
  • 9,869
  • 6
  • 42
  • 59
11

Better to use Completer, because if your operation is too short or the device is too slow, then the dialogContext variable will not be initialized and you can't close the dialog.

final dialogContextCompleter = Completer<BuildContext>();
showDialog<void>(
  context: context,
  barrierDismissible: false,
  builder: (BuildContext dialogContext) {
    if(!dialogContextCompleter.isCompleted) {
      dialogContextCompleter.complete(dialogContext);
    }
    return AlertDialog(
      content: CircularProgressIndicator(),
    );
  },
);

// Close progress dialog
final dialogContext = await dialogContextCompleter.future;
Navigator.pop(dialogContext);
Mihail Ya
  • 361
  • 3
  • 6
  • 1
    I think this should be the accepted answer. I had to detect whether multiple dialogs were opened and handle situations to only have single dialog opened. This was the only way to reliably close them. – user3056783 Oct 08 '21 at 19:33
4

This will close the dialog/alert box.

Navigator.of(context).pop();
4

In 2023 here is the latest way to do that. Because in my case Navigator.of(context).pop(); didn't work

Navigator.of(context, rootNavigator: true).pop();
imalixch
  • 43
  • 9
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Mar 22 '23 at 19:59
2
showDialog(
  context: context,
  builder: (BuildContext context) => Center(
    child: CircularProgressIndicator(),
  ),
);

await Future<int>.delayed(Duration(seconds: 3));

Navigator.of(context, rootNavigator: true).pop();
Dhairya Lakhera
  • 4,445
  • 3
  • 35
  • 62
1

Add on to Günter's answers. If you need to dismiss it when the user clicks elsewhere change this property to true

barrierDismissible: true,
Jeff
  • 253
  • 1
  • 2
  • 10
1

Try this. It will definitely work. use the context of pageBuilder in Navigator to pop the dialog from screen.

showGeneralDialog(
     context: context,
     barrierLabel: "XYZ",
     barrierDismissible: true,
     barrierColor: Colors.black.withOpacity(0.7),
     pageBuilder: (dialogContext, __, ___) {
       return Center(
        child: Container(
          height: 240,
          margin: const EdgeInsets.symmetric(horizontal: 15),
          decoration: bd,
          child: SizedBox.expand(
              GestureDetector(
                   onTap: (){
                       Navigator.pop(dialogContext);
                    },
                    child: const Padding(
                       padding: EdgeInsets.fromLTRB(10,0,10,0),
                       child: Icon(Icons.close, size: 26, color:Colors.white),
                     ),
               ),
           )
         ) 
       );
     }
  );

 
Waqar Ahmed
  • 349
  • 4
  • 11