Flutter - use WillPopScope with custom dialog to confirm app exit

1,706

Solution 1

Yes, you are right. So that's how it should look:

Future<bool> _promptExit()  async {

    bool canExit;

    AwesomeDialog dlg = AwesomeDialog(
      context: context,
      dialogType: DialogType.QUESTION,
      animType: AnimType.BOTTOMSLIDE,
      title: Strings.prompt_exit_title,
      desc: Strings.prompt_exit_content,
      dismissOnTouchOutside: true,
      btnCancelOnPress: () => canExit = false,
      btnOkOnPress: () => canExit = true,
      btnOkText: Strings.yes,
      btnCancelText: Strings.no
    );

    await dlg.show();
    return Future.value(canExit);
}

Solution 2

showDialog will not pop the dialog itself. So you need to use Navigator.of(context).pop() and get the return value.

awesomeDialogs wrap the pop() function itself and do nothing to the return value (awesome_dialog.dart)

   ...
    pressEvent: () {
      dissmiss();
      btnOkOnPress?.call();
    },
   ...
    pressEvent: () {
      dissmiss();
      btnCancelOnPress?.call();
    },
   ...

dissmiss() {
  if (!isDissmisedBySystem) Navigator.of(context, rootNavigator:useRootNavigator)?.pop();
}
...

So you need to handle the return value by yourself and don't use pop() again:

var result;

AwesomeDialog dlg = AwesomeDialog(
  context: context,
  dialogType: DialogType.QUESTION,
  animType: AnimType.BOTTOMSLIDE,
  title: Strings.prompt_exit_title,
  desc: Strings.prompt_exit_content,
  dismissOnBackKeyPress: false,
  useRootNavigator: true,
  btnCancelOnPress: () {result = false;},
  btnOkOnPress: () {result = true;},
  btnOkText: Strings.yes,
  btnCancelText: Strings.no
);

await dlg.show();

return result;
Share:
1,706
user1209216
Author by

user1209216

Updated on December 27, 2022

Comments

  • user1209216
    user1209216 over 1 year

    I've implemented app exit confirmation this way:

     return WillPopScope(
          onWillPop: _promptExit,
          child: Container() /*Remaining window layout*/
    

    _promptExit funcion shows dialog to confirm exit:

    return showDialog(
          context: context,
          builder: (context) => new AlertDialog(
            shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(20.0))),
            title: new Text(Strings.prompt_exit_title),
            content: new Text(Strings.prompt_exit_content),
            actions: <Widget>[
              FlatButton(
                child: new Text(Strings.no),
                onPressed: () => Navigator.of(context).pop(false),
              ),
              SizedBox(height: 16),
              FlatButton(
                child: new Text(Strings.yes),
                onPressed: () => Navigator.of(context).pop(true),
              ),
            ],
          ),
        ) ??
            false;
    

    It works, but I want to use custom dialog instead of standard one: https://github.com/marcos930807/awesomeDialogs

    It calls showDialog internally, so I tried this way:

     AwesomeDialog dlg = AwesomeDialog(
          context: context,
          dialogType: DialogType.QUESTION,
          animType: AnimType.BOTTOMSLIDE,
          title: Strings.prompt_exit_title,
          desc: Strings.prompt_exit_content,
          dismissOnBackKeyPress: false,
          useRootNavigator: true,
          btnCancelOnPress: () {  Navigator.of(context).pop(false);},
          btnOkOnPress: () {   Navigator.of(context).pop(true);},
          btnOkText: Strings.yes,
          btnCancelText: Strings.no
        );
    
        return dlg.show() ?? false;
    

    But I can't pop this way, I am getting black screen. What should I do?