0

I set _visible to false after 1 second delay of the code, but the dialog remains on the screen. I wait for the dialog to disappear after a second. How can I set this?

                 return BuildNumButton(
                          buttonColorDisable: _buttonColorRed(),
                          color: colorList[index],
                          number: numberList[index],
                          isDisable: disableButtons.contains(index),
                          callback: () async {
                            disableButtons.add(index);

                            CalculateScore.sumNumbers(numberList[index]);
                            CalculateScore.calculateScore();
                            _updateScore();
                            if (CalculateScore.answer) {
                              if (!CalculateScore.endGame) {
                                _show();

                                await Future.delayed(
                                    const Duration(milliseconds: 1000), () {
                                  setState(() {
                                    _visible = !_visible;
                                  });
                                });

                                disableButtons.clear();
                                _updateList();
                                _updateButtonColor();
                              }
                              _updateTarget();
                            }
                          },
                        );

     _show() {
 return AnimatedOpacity(
  opacity: _visible ? 1.0 : 0.0,
  duration: const Duration(milliseconds: 500),
  child: _showDialog(context),
 );
}

_showDialog(BuildContext context) {
 return showDialog<String>(
  useSafeArea: true,
  barrierColor: Colors.red.withOpacity(0.5),
  barrierDismissible: false,
  context: context,
  builder: (BuildContext context) => const Icon(
    Icons.check_rounded,
     size: 100,
  ),
 );
}
 
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
a.snss
  • 143
  • 3
  • 10

3 Answers3

1

What you are doing is actually wrong.

AnimatedOpacity is a Widget & showDialog is a function. When you are passing showDialog as AnimatedOpacity's child its somehow working but breaking the further process. As you can see a simple Future.delayed is not working anymore. You can test this by simply putting a print command above & below the _show();

When you are calling AnimatedOpacity on button call its actually creating a new widget over your current widget. Now as your current code is broken the process is not working & state is not updating anymore.

To fix this there are three options

  1. Remove the animated opacity & show dialog normally. See example here
  2. Use any package which can provide dialog animations like opacity.
  3. Use showGeneralDialog. See example here (Reference from here)
Aakash Kumar
  • 1,069
  • 7
  • 11
0

To close _showDialog do yo need call Navigator.pop(context);

Add this inside your Future.delayed()

await Future.delayed(const Duration(milliseconds: 1000), () {
    setState(() {
       _visible = !_visible;
       Navigator.pop(context);
    });
});
Felipe Vergara
  • 849
  • 7
  • 12
0

When you call return showDialog<String>(... you are not on this screen:

return AnimatedOpacity(
  opacity: _visible ? 1.0 : 0.0,
  duration: const Duration(milliseconds: 500),
  child: _showDialog(context),
 );

So it is not matter if you change _visible if you want to close the dialog page you need to call: Navitagor.pop(context); inside your callback function;

Navitagor.pop(context);
setState(() {
  _visible = !_visible;
});
Mehmet Ali Bayram
  • 7,222
  • 2
  • 22
  • 27