92

How to update the Homepage just after the showDialog() is dismissed/disposed? Doesn't seem like it has an onDispose() function.

Found another possible Answer : The WillPopScope can help detect if the back button is pressed.

The widget that will be used in the showDialog, in its build function the widget can be wrapped in return new WillPopScope(child: ______, onWillPop: _______); The code can be run in the onWillPop function. This can update the Homepage below.

zackygaurav
  • 4,369
  • 5
  • 26
  • 40
Ant D
  • 2,481
  • 6
  • 18
  • 34

10 Answers10

200

Simply use await or then. the code in then block will be run after the dialog is dismissed.

showDialog(
  // Your Dialog Code
).then((val){
  Navigator.pop(_context);
});
Vahid
  • 6,639
  • 5
  • 37
  • 61
Jaldip Katre
  • 3,216
  • 1
  • 19
  • 14
29

It really depends on the type of updates you want to have.

However, this is a simple example that may help you figure it out.

enter image description here

class Home extends StatefulWidget {
  @override
  _HomeState createState() => new _HomeState();
}

class _HomeState extends State<Home> {
  String _homeData = "initial data";

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(_homeData),
            new RaisedButton(
              child: new Text("Show Dialog"),
              onPressed: ()async{
                bool shouldUpdate = await showDialog(
                  context: this.context,
                  child:new AlertDialog(
                    content: new FlatButton(
                      child: new Text("update home"),
                      onPressed: () => Navigator.pop(context, true),
                    ),
                  ),
                );
                setState(() {
                  shouldUpdate ? this._homeData = "updated" : null;
                });
              },
            ),
          ],
        ),
      ),
    );
  }
}
Falko
  • 17,076
  • 13
  • 60
  • 105
Shady Aziza
  • 50,824
  • 20
  • 115
  • 113
  • Can I get the same result if the back button is pressed on the phone? If the user clicks either of the buttons. – Ant D Apr 07 '18 at 13:14
  • The back button on the phone will return null, hence `setState((){ shouldUpdate==true||shouldUpdate==null?this._homeData = "updated":null; });` – Shady Aziza Apr 07 '18 at 13:18
  • Actually this will result in also updating the home if user dismiss the modal by clicking outside of it too – Shady Aziza Apr 07 '18 at 13:19
  • I think your issue is now more of UX issue, I do not know your use case for having the user dismiss the dialog and still get data updated, updating data should be controlled by triggering a meaningful action unlike dismissing – Shady Aziza Apr 07 '18 at 13:20
  • Use case: I am trying out a Flutter lib 'SpriteWidget'. I have a main 'node' to which other 'sprites/nodes' are attached. I am showing a new arrangement/layout of the attached nodes in a 'showDialog' and the visible backpage is blank as I want it . So when I dismiss this dialog, with either a button or the phone button, I want to run code to reassemble the backpage layout. Thank you. – Ant D Apr 07 '18 at 14:38
  • Found as answer, I've added it to the question above. – Ant D Apr 13 '18 at 05:41
8

If you have made another StatefulWidget for your DialogBox and onDissmissed, you want to call some function in the "dialog calling widget". You can this snippet.

await showDialog(
      context: context,
      builder: (_) => MenuBox(),
);
print("now closed");
Manish
  • 417
  • 5
  • 10
7

Mobile apps typically reveal their contents via full-screen elements called "screens" or "pages". In Flutter these elements are called routes and they're managed by a Navigator widget. The navigator manages a stack of Route objects and provides methods for managing the stack, like Navigator.push and Navigator.pop.

showDialog(
            context: context,
            child: new AlertDialog(
                title: const Text("Your Title"),
                content: const Text(
                  ...
                   Your Message
                  ...),
                actions: [
                new FlatButton(
                  child: const Text("Ok"),
                  onPressed: () => Navigator.pop(context),
                ),
              ],
            ),
        );

You can check Official Document

Ekta Bhawsar
  • 746
  • 11
  • 26
  • Will it update if the back button is pressed on the phone and not the button on the dialog, to dismiss the dialog? – Ant D Apr 07 '18 at 12:46
  • Is it possible to have a page behave as a dialog. That is - (1) The page is not full screen, the page size can be controlled and - (2) The backpage is visible from the sides of the overlaid page? so I can use Navigator.pushnamed. Thank you. – Ant D Apr 07 '18 at 17:51
  • Found as answer, I've added it to the question above. – Ant D Apr 13 '18 at 05:41
4

When tapping outside the dialog the return is null, so I expect a potential null and check for null, which is then false.

onPressed: () async {
bool? result = await showDialog(
  context: context,
  builder: (BuildContext context) {
    return AlertDialog(
      title: Text('Select Entity'),
      content: setupAlertDialogContainer(),
    );
  },
);
if (result ?? false) {
  doWhatYouNeedTo();
}
Wesley Barnes
  • 554
  • 4
  • 18
2

Use; .whenComplete(funcName/*not funcName() !*/); after the showDialog()

funcName() {
//Your code
}
Smh
  • 249
  • 2
  • 4
1

Noticed a couple of the above answers were a bit out of date due to the "child" construct used with the AlertDialog object being deprecated now.

Here is what I use now instead for a blocking alert dialog:

          showDialog(
            context: context,
            builder: (BuildContext context) {
              // return object of type Dialog
              return AlertDialog(
                title: new Text("Conversation Request"),
                content:
                    new Text("Have a conversation with this person"),
                actions: <Widget>[
                  // usually buttons at the bottom of the dialog
                  new FlatButton(
                    child: new Text("Accept"),
                    onPressed: () {
                      performAccept();
                    },
                  ),
                  new FlatButton(
                    child: new Text("Ignore"),
                    onPressed: () {
                      performIgnore();
                    },
                  )
                ],
              );
            },
          )
E.Bradford
  • 783
  • 7
  • 21
1

There are two approaches.

  1. Use async-await

    bool shouldUpdate = await showDialog<bool>(...);
    if (shouldUpdate) {
      setState(() {
        // we should update the UI
      });
    }
    
  2. Use then

    showDialog<bool>(...).then((shouldUpdate) {
      if (shouldUpdate) {
        setState(() {
          // we should update the UI
        });
      }
    });
    
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
1

you can use this code below. It will invoke onDismiss and onShow dialog.

   void baseDialog(
        {required Widget content,
        required BuildContext context,
        required Function onDialogShow,
        required Function onDialogDismiss,
        bool barrierDismissible = true}) async {
      onDialogShow.call();
    
      await showDialog(
        context: context,
        barrierDismissible: barrierDismissible,
        builder: (_) {
          return AlertDialog(
            shape: const RoundedRectangleBorder(
              borderRadius: BorderRadius.all(
                Radius.circular(12),
              ),
            ),
            content: Material(color: Colors.white, child: content),
          );
        },
      );
      onDialogDismiss.call();
    }
xaldarof
  • 75
  • 1
  • 7
0

For me, I used Bloc state management to handle this. The idea is:

//On Dialog
clickOKAction: () => blocCubit.emitOKActionState()
...

//On the bloc file
fun emitOKActionState(){
   emit(OKActionState());
}

//On Widget
listener: (context, state) async {
   if(state is OKActionState) {
        // HANDLE YOUR ACTION HERE
   }
}

Because after showing Dialog, the current widget will be disposed. So you can not use anything related to context for eg, because it's unmounted. This may help solve error like:

This widget has been unmounted, so the State no longer has a context (and should be considered defunct)

Huy Nguyen
  • 1,032
  • 14
  • 38