1

There are 3 ways the AlertDialog can be dismissed (in my example):

  1. Tapping outside its barrier. ('to cancel')
  2. Tapping a button A which will call pop(). ('to proceed')
  3. Tapping a button B which will call pop(). (to 'cancel')

I wish to run some code in a then() callback after the AlertDialog is closed. This code will be dependent on HOW it was closed.

Note: I am using the then() callback so I can detect if the AlertDialog was dismissed not by a button.

Is this possible?

      showDialog(context: context, builder: (context) => AlertDialog(
        title: Text('Grant access'),
        actions: [
/// Button 'A'
          OutlinedButton(onPressed: (){
              Navigator.of(context).pop();
              /// Some more code
          }, child: Text('Grant access')),

/// Button 'B'
          OutlinedButton(onPressed: () {
            Navigator.of(context).pop();
          }, child: Text('Cancel'))
        ],
      )).then((value) async {
        // Code after closure. Can I detect what way the AlertDialog was dismissed?
      });
Kdon
  • 892
  • 6
  • 19

2 Answers2

2

You could pass data like Navigator.of(context).pop('something') then receive its value in .then

showDialog(context: context, builder: (context) => AlertDialog(
    title: Text('Grant access'),
    actions: [
      OutlinedButton(onPressed: (){
          Navigator.of(context).pop('Button A');
          /// Some more code
      }, child: Text('Grant access')),

      OutlinedButton(onPressed: () {
        Navigator.of(context).pop('Button B');
      }, child: Text('Cancel'))
    ],
  )).then((value) async {
    // Check if the value returned from showDialog is null
  if (value == null) {
    // If value is null, it means that the dialog was closed by tapping outside
    print('Dialog closed by tapping outside');
  } else {
    // If value is not null, it means that the dialog was closed with a value
    // Print the value for debugging purposes
    print('Dialog closed with value: $value');
  }
});

But i recommend you create a CustomDialog class with callback, it should be better.

Tamizh
  • 118
  • 3
ShinZ
  • 36
  • 3
1

You can use the await keyword with the showDialog() function, and then check the value returned by the function to determine the dismissal method.

var result = await showDialog(
  context: context,
  builder: (context) => AlertDialog(
    title: Text('Grant access'),
    actions: [
      OutlinedButton(
        child: Text('Grant access'),
        onPressed: () {
          Navigator.of(context).pop('Granted');
        },
      ),
      OutlinedButton(
        child: Text('Cancel'),
        onPressed: () {
          Navigator.of(context).pop('Cancelled');
        },
      ),
    ],
  ),
);

if (result == 'Granted') {
  // run code for dismissal by tapping button A
} else if (result == 'Cancelled') {
  // run code for dismissal by tapping button B or outside barrier
} else {
  // run code for dismissal by other means (e.g. back button)
}
Hamed
  • 5,867
  • 4
  • 32
  • 56