skip to Main Content

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');

2

Answers


  1. Here’s an example, you can do this,

        import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: ScreenA(),
        );
      }
    }
    
    class ScreenA extends StatefulWidget {
      @override
      _ScreenAState createState() => _ScreenAState();
    }
    
    class _ScreenAState extends State<ScreenA> {
      bool isDialogOpen = false;
    
      void openDialog() {
        setState(() {
          isDialogOpen = true;
        });
      }
    
      void closeDialog() {
        setState(() {
          isDialogOpen = false;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Screen A'),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: () {
                    openDialog();
                    // Use Future.delayed here to navigate to Screen B after a delay
                    Future.delayed(Duration(seconds: 2), () {
                      Navigator.of(context).push(
                        MaterialPageRoute(builder: (context) => ScreenB()),
                      );
                    });
                  },
                  child: Text('Show Dialog and Navigate to Screen B'),
                ),
                if (isDialogOpen) MyDialog(closeDialog: closeDialog),
              ],
            ),
          ),
        );
      }
    }
    
    class ScreenB extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Screen B'),
          ),
          body: Center(
            child: Text('Screen B Content'),
          ),
        );
      }
    }
    
    class MyDialog extends StatelessWidget {
      final Function closeDialog;
    
      MyDialog({required this.closeDialog});
    
      @override
      Widget build(BuildContext context) {
        return AlertDialog(
          title: Text('My Dialog'),
          content: Text('This is a custom dialog.'),
          actions: <Widget>[
            ElevatedButton(
              onPressed: () {
                closeDialog();
              },
              child: Text('Close Dialog'),
            ),
          ],
        );
      }
    }
    
    Login or Signup to reply.
  2. 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);
                  }
                });
              },
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search