flutterflutter-navigationflutter-go-routerflutter-dialog

is there any way in flutter to persist dialog when moving from one screen to another?


I have a two screens. Screen A and Screen B. I have a button on Screen A. when I click on it. It shows a dialog. after that I have a used Future.delayed(). when duration is over I move to the Screen B. but dialog also closes here. I want the dialog to be remain open and should no be closed until I called. context.pop() method;

I am using go_router package in my app.

This is how my onPressed look like

showGeneralDialog(context: context,barrierColor: Colors.white.withOpacity(0),
pageBuilder: (context, animation, secondaryAnimation) => SplashView(),
await Future.delayed(Duration(seconds: 2));
GoRouter.of(context).go('/home');

Solution

  • You can do that by wrapping the Dialog with an Overlay widget and placing that widget in the global (app level) section outside your class to make it independent of the route changes, and create a function to show/hide the dialog.

    You may see a demo here. As an added bonus I also created a function to change the text inside the dialog when navigation is complete and to show or hide the "close dialog" button conditionally.

      Define Widget and Function globally:
      
      static void setDialogText(String newText, bool show) {
        dialogText = newText;
        showCloseButton = show;
    
        if (isOpen) {
          _overlayEntry?.markNeedsBuild();
        }
      }
    
      static void show(BuildContext context) {
        isOpen = true;
        _overlayEntry = OverlayEntry(
          builder: (context) {
            return Center(
              child: Dialog(
                backgroundColor: Colors.grey,
                child: SizedBox(
                  height: 60.0,
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: <Widget>[
                      Text(
                        dialogText,
                      ),
                      !showCloseButton
                          ? const SizedBox.shrink()
                          : ElevatedButton(
                              onPressed: () {
                                // Close the dialog
                                isOpen = false;
                                _overlayEntry?.remove();
                              },
                              child: const Text('Close Dialog')),
                    ],
                  ),
                ),
              ),
            );
          },
        );
    
        Overlay.of(context).insert(_overlayEntry!);
      }
      
      Inside a class call it like this: 
      
      onPressed: () {
                OverlayDialog.show(context);
                Future.delayed(const Duration(seconds: 3), () {
                  if (OverlayDialog.isOpen) {
                    Navigator.of(context).push(
                      MaterialPageRoute(builder: (context) => const ScreenB()),
                    );
                    OverlayDialog.setDialogText('Welcome to ScreenB!', true);
                  }
                });
              },