FlutterToast icon indicating copy to clipboard operation
FlutterToast copied to clipboard

Handle toast globally via StateManagement solution ?

Open guillaumeboussion opened this issue 2 years ago • 9 comments

Hi,

First, thanks for this powerful package. I'd like to be able to manage toast apparition using a state management solution such as Riverpod. But to do this, I need to be able to display a toast from a single entry point in the app.

The thing is, in my MaterialApp, I try to instantiate the ftoast from the MaterialApp context, but then, when I use the ftoast from an other page in the app (using Riverpod), the toast is not showing, and an assertion failed error is thrown

'_overlay != null': is not true.

Also I need to mention that I don't want to use the Fluttertoast.showToast() because we want to display icon next to the text..!

Do you think there's a simple solution for this ?

guillaumeboussion avatar Jul 07 '22 09:07 guillaumeboussion

you found a solution yet ?

Abdul-AzeezO avatar Aug 22 '22 20:08 Abdul-AzeezO

@guillaumeboussion any updates ? I want to use it with bloc

thorizer avatar Oct 05 '22 14:10 thorizer

You can put your your listener e.g. BlocListener in MaterialApp.builder with Overlay widget wrapping it

    MaterialApp.router(
      builder: (context, child) {
        return Overlay(
          initialEntries: [
            OverlayEntry(
              builder: (context) {
                return BlocListener(
                  listener: (context, state) {
                    FToast().init(context).showToast();
                  },
                  child: child,
                );
              },
            )
          ],
        );
      },
    );

jasontcs avatar Oct 26 '22 08:10 jasontcs

I am facing a similar issue (want to call from outside a widget) - I want to show a toast from a firebase FCM listener. I was using another_flushbar without issues, but due to the design requirements of a new toast, I thought I'd give fluttertoast a go

However, whilst before I could use the globalkey for the navigator state which is passed in to the MaterialApp initializer, it seems fluttertoast doesn't play nicely with it.

The call is made to showToast - but nothing appears, and then after the duration, I get the

'_overlay != null': is not true.

Error as above

I would have though using this plugin in the way I've described would be pretty common - so a little surprised I'm hitting this roadblock :-(

Appreciate any ideas?

Code snippet below. With another_flushbar the context usage was fine - I can navigate around etc from within the listener callback using navigatorKey.currentContext!

    FirebaseMessaging.onMessage.listen(
      (RemoteMessage message) async {

        if (message.data['notificationType'] == "voip") {
          final notificationView = await NotificationView.fromVoipMessage(message);

          final fToast = FToast();
          fToast.init(navigatorKey.currentContext!);

          fToast.showToast(
            toastDuration: const Duration(seconds: 5),
            gravity: ToastGravity.CENTER, 
            child: NotificationToastFactory.createIncomingCallNotification(
              navigatorKey.currentContext!,
              notificationView!,
            ),
          );
          return;
        }
    );
  }

codecoded avatar Oct 28 '22 04:10 codecoded

Hey! Maybe it's too late, but it can be useful for other developers because the same question is asked regularly.

I think I found a solution for using context from Navigator key but I didn't test it a lot and don't know how it will affect performance. At least it works fine for me and I'll be glad to get any feedback and improvements.

So you need to create overlay manually in MaterialApp (or it's analogs):

MaterialApp(
  builder: (context, child) => Overlay(
    initialEntries: [
      if (child != null) ...[
        OverlayEntry(
          builder: (context) => child,
        ),
      ],
    ],
  ),
 navigatorKey: yourNavKey,

And after this you can use context from navigator, e.g.

FToast fToast = FToast();
fToast.init(yourNavKey.currentContext!);

If this works stable, I think it's better to add this information to package manual and/or example, @ponnamkarthik what do you think?

Best regards, Alex

AlexSeednov avatar Feb 09 '23 06:02 AlexSeednov

Thanks @AlexSeednov

yes its helps i will update the example app code to use Navigator Key

ponnamkarthik avatar Feb 09 '23 06:02 ponnamkarthik

I tried this and I get the same error - overlay nil.

I added the builder as per your example - copy pasted actually, then in my code, do a navigator.push and then a navigator.pop. Then trying to show a toast results in the error.

ref: https://github.com/ponnamkarthik/FlutterToast/issues/424

Hey! Maybe it's too late, but it can be useful for other developers because the same question is asked regularly.

I think I found a solution for using context from Navigator key but I didn't test it a lot and don't know how it will affect performance. At least it works fine for me and I'll be glad to get any feedback and improvements.

So you need to create overlay manually in MaterialApp (or it's analogs):

MaterialApp(
  builder: (context, child) => Overlay(
    initialEntries: [
      if (child != null) ...[
        OverlayEntry(
          builder: (context) => child,
        ),
      ],
    ],
  ),
 navigatorKey: yourNavKey,

And after this you can use context from navigator, e.g.

FToast fToast = FToast();
fToast.init(yourNavKey.currentContext!);

If this works stable, I think it's better to add this information to package manual and/or example, @ponnamkarthik what do you think?

Best regards, Alex

aneeskA avatar Feb 24 '23 17:02 aneeskA

I tried this and I get the same error - overlay nil.

I added the builder as per your example - copy pasted actually, then in my code, do a navigator.push and then a navigator.pop. Then trying to show a toast results in the error.

ref: #424

Hey! Maybe it's too late, but it can be useful for other developers because the same question is asked regularly. I think I found a solution for using context from Navigator key but I didn't test it a lot and don't know how it will affect performance. At least it works fine for me and I'll be glad to get any feedback and improvements. So you need to create overlay manually in MaterialApp (or it's analogs):

MaterialApp(
  builder: (context, child) => Overlay(
    initialEntries: [
      if (child != null) ...[
        OverlayEntry(
          builder: (context) => child,
        ),
      ],
    ],
  ),
 navigatorKey: yourNavKey,

And after this you can use context from navigator, e.g.

FToast fToast = FToast();
fToast.init(yourNavKey.currentContext!);

If this works stable, I think it's better to add this information to package manual and/or example, @ponnamkarthik what do you think? Best regards, Alex

I have the same problem, have you solved it? @aneeskA @ponnamkarthik

buptyyf avatar Jun 12 '23 08:06 buptyyf