Home > Software design >  Trying to use showDialog()/show Pop up on app startup
Trying to use showDialog()/show Pop up on app startup

Time:04-04

What I want to achieve: I want to open a pop up explaining my app when it starts.

My approach: As far as I understand it from googling the issue, I should use the showDialog() method. In its most basic form:

showDialog(
    context: context,
    builder: (context) {
      return Text('data');
    });

I tried returning actual dialogs (e.g. AlertDialog) but it doesn't change the behavior so I'm just using Text() with a string as a placeholder for now.

The problem:

No matter where I place the showDialog function, it doesn't work as intended (also see scrennshots below):

  • Placing it in initState: I get an error message about inherited Widgets being called before the initState is done an explanation about dependiencies I can barely follow.
  • Placing it in the build method: I get an error message that setState() or markNeedsBuild() gets called while the app is already buildung widgets.
  • Placing it in DidChangeAppLifeCycleState(): This is actually working and opening the pop when I pause the app and then resume it. It is not opening on app startup though.
  • Wrapping it in WidgetsBinding.instance!.addPostFrameCallback(): An idea I picked up here: enter image description here

    From build method:

    enter image description here

    From DidChangeAppLifecycleState (the "succesful" variant:

    enter image description here

    CodePudding user response:

    Will you please try below code in your init method? I hope this may work.

    Future.delayed(Duration.zero, () async {
      myFunction();
    });
    

    CodePudding user response:

    One of the methods with WidgetsBinding.instance!.addPostFrameCallback() works fine . If you show a normal show dialog with the press of a button too it will produce the same result. Here, you need to wrap the text("data") in a dialog widget such as alertDialog or simpleDialog widget as needed and it will display the dialog within the current scaffold as -

      WidgetsBinding.instance!.addPostFrameCallback((_) async {
          return await showDialog(
              context: context,
              builder: (context) {
                return AlertDialog(
                  content: Text("data"),
                );
              });
        }); 
    

    I tried adding this in the init state and the dialog pops up fine when I restart the app

    CodePudding user response:

    Using WidgetsBinding.instance?.addPostFrameCallback inside initState perform its inner task after the 1st frame is complete.

    addPostFrameCallback Schedule a callback for the end of this frame.

    Next issue arise for not having material. You can directly return AlertDialog on builder or wrap with any material widget like Material, Scaffold..

      @override
      void initState() {
        super.initState();
        
        WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
          showDialog(
            context: context,
            builder: (context) {
              return const AlertDialog(
                content: Text('data'),
              );
            },
          );
        });
      }
    

    CodePudding user response:

    Thanks a lot for your answers. I ficed the issue by rewriting with your suggestions; and it works. I tihnk the issue was that I did not have _ or anything else in my WidgetsBinding code. So I did:

    WidgetsBinding.instance?.addPostFrameCallback(() {})
    

    instead of

    WidgetsBinding.instance?.addPostFrameCallback((_) {})
    
  • Related