Apri
Apri

Reputation: 1515

Flutter show SnackBar without context

I have a flutter app that makes many different http requests in different screens of the app. Now, I want to implement some general error handling, for example, whenever there is no connectivity, I want to show a SnackBar, no matter where I currently am in the app. I managed to write a method that gets called everytime there is an exception in one of my requests. Now, I want to show the SnackBar from within this method. But I don't have access to the BuildContext in this method, and I can't pass it as a parameter to the method either.

So, is there a way to show a SnackBar without having the context? For example, a method to get the context of the currently active screen, and then using it to show the SnackBar?

Upvotes: 15

Views: 7593

Answers (2)

Miguel Ruivo
Miguel Ruivo

Reputation: 17756

Suggesting to use a package as pointed by Kaival is not the right way to go, since you won't learn the right solution for your problem other than relying on 3rd party packages and also over-engineering your app with those when sometimes not needed.

Tu use a SnackBar without a context it's actually very simple through a key. You can create a GlobalKey<ScaffoldState> wherever you want and assign it to the Scaffold where you want to display the SnackBar.

GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

Widget build(BuildContext context) {
   return Scaffold(key: _scaffoldKey);
}

and then anywhere you want, you can check its state to launch a SnackBar as such:

void foo() {
 if(_scaffoldKey.currentState != null) {
   _scaffoldKey.currentState.showSnackBar();
 }
}

You just need to make sure the state is mounted (this is, the Scaffold you want is available, before displaying it.

Just make sure that you are using the new ScaffoldMessenger API you may want to consider adding it to your root MaterialApp a ScaffoldMessengerState so you can use it everywhere.

final GlobalKey<ScaffoldMessengerState> rootScaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>();
MaterialApp(
  scaffoldMessengerKey: rootScaffoldMessengerKey,
  home: ...
)

and call it accordingly

rootScaffoldMessengerKey.currentState.showSnackBar();

Refer to the docs for more info.

Upvotes: 19

gbaccetta
gbaccetta

Reputation: 4577

Hi you could use a globalkey as a navigation key associated with your MaterialApp. That would allow you to also navigate eventually to an error scree or anywhere else.

With the globalkey, you will be able to retrieve the context everywhere (at least when your app is in foreground and there actually is a context).

Although it is not always really reccomended to have a global variable, you can do Something like this: In your main create a GlobalVariable class containing the key:

class GlobalVariable {
  /// This global key is used in material app for navigation through firebase notifications.
  static final GlobalKey<NavigatorState> navigatorState = GlobalKey<NavigatorState>();
}

Than declare the key as navigation key in your MaterialApp:

MaterialApp(
        navigatorKey: GlobalVariable.navigatorState,

Finally access the key and context everywhere:

GlobalVariable.navigatorState.currentContext

Upvotes: 3

Related Questions