skip to Main Content

I’d like to display a widget on the then-current screen when some asynchronous data comes in. However, I don’t want it to be a SnackBar or a MaterialBanner, but rather my own widget with my own look and feel.

The issue is that I haven’t been able to figure out how to determine which "screen"/route is current; i.e. which State to update. I’ve looked at Scaffold.of, RouteObserver, provider, and a few other things, but haven’t been able to get anything to work.

I’ve also looked at ScaffoldMessenger but haven’t figured out how to make it display anything besides a SnackBar or MaterialBanner. (I know that both SnackBar and MaterialBanner are somewhat customizable but that’s not what I’m looking for.)

To simplify a bit, what I need is the xxxxx below:



    static void gotData(Object data) {
      Widget msgbox = messageBox(data); // similar to SnackBar. a message widget.
      globalstuff.msgbox = msgbox;      // my routes will position/display this in each build()
      xxxxx.setState(() {});            // how do i get xxxxx?
    }

This might seem basic/silly but I just haven’t been able to make any progress.

2

Answers


  1. Chosen as BEST ANSWER

    I was able to use RouteObserver to keep track of the current route, using information from this answer:

    https://stackoverflow.com/a/54206693/936098

    Armed with the current route and the ability to call setState() on it, all that remained was to modify my various routes' build() methods to display a popup with the async information when appropriate.


  2. You can use an overlay to display your own customized widget instead of the default Snackbar.

    Here’s a code snippet for that :

    Future<void> showCustomNotification({
      required BuildContext context,
      required Widget child,
    }) async {
      OverlayState? overlayState = Overlay.of(context);
      OverlayEntry overlayEntry = OverlayEntry(
        builder: (c) {
          return Positioned(
            bottom: 16,
            left: 0,
            right: 0,
            child: Material(
              color: Colors.transparent,
              child: child,
            ),
          );
        },
      );
      overlayState?.insert(overlayEntry);
      overlayState?.setState(() {});
      await Future.delayed(const Duration(seconds: 1, milliseconds: 500));
      overlayEntry.remove();
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search