5

I want to autoclose dialog a few seconds after opening. The solution that I found is to call Navigator.of(context).pop(); delayed and it works. But the problem occurs if I closed it manually (by clicking outside) before the execution of the Navigator.pop command. Then Navigator.pop just closes the app and I see just a black screen. I need a way to destroy this delay on closing the dialog or to find another workaround.

showDialog(
  context: context,
  builder: (BuildContext builderContext) {
    Future.delayed(Duration(seconds: 5), () {
      Navigator.of(context).pop();
    });

    return AlertDialog(
      backgroundColor: Colors.red,
      title: Text('Title'),
      content: SingleChildScrollView(
        child: Text('Content'),
      ),
    );
  }
);

4 Answers 4

17

You can use a Timer to achieve this. You can cancel the timer whenever you want.

Declare a timer property in your class:

Timer _timer;

And change your showDialog code like:

showDialog(
  context: context,
  builder: (BuildContext builderContext) {
    _timer = Timer(Duration(seconds: 5), () {
      Navigator.of(context).pop();
    });

    return AlertDialog(
      backgroundColor: Colors.red,
      title: Text('Title'),
      content: SingleChildScrollView(
        child: Text('Content'),
      ),
   );
  }
).then((val){
  if (_timer.isActive) {
    _timer.cancel();
  }
});
Sign up to request clarification or add additional context in comments.

Comments

3

In this case, you are using the wrong context.

Try to change the context you are using in the "pop"

You have this BuildContext builderContext, use that builderContext like:

Navigator.of(builderContext).pop();

1 Comment

Can you tell me what's the difference? Thanks in advance...
1

You can use different way of executing pop() request using Timer

_timer = Timer(Duration(seconds: _timerTimeoutInterval), () {
    Navigator.of(context).pop();
});

And in case you want to cancel the timer you can call this:

if (_timer != null && _timer.isActive) {
  _timer.cancel();
}

3 Comments

You can close it manually by creating button and executing Navigator pop method in that button's onPress callback.
Yes, but I want to close it by clicking outside.
Ahhhh sorry, I read the question wrong. In order to close the dialog and cancel that execution of a pop, you need to use timer, that can be cancelled on demand. I will edit my initial answer.
0
await showDialog(
  context: context,
  builder: (BuildContext dialogContext) {
    Future.delayed(Duration(seconds: 5),() => Navigator.of(dialogContext).pop());
    return AlertDialog(
      backgroundColor: Colors.red,
      title: Text('Title'),
      content: SingleChildScrollView(
        child: Text('Content'),
      ),
   );
  }
);
// any code which will be executed after the dialog is closed
// either by the timer or by user action

Note: It is important to use the dialog context because if you use pop on other context it is likely that you are calling pop on the parent widget and not the dialog.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.