0

I have a problem and it is with respect to the content of the SnackBar. I created a class where it contains the following:

class ActionSuccessSnackBar extends StatelessWidget {
  const ActionSuccessSnackBar({
    Key key,
    this.isCreation,
    this.name,
  }) : super(key: key);

  final bool isCreation;
  final String name;

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        Expanded(
          child: Container(
            child: Text(
              name,
              style: TextStyle(
                fontWeight: FontWeight.bold,
              ),
            ),
          ),
        ),
        Container(
          child: Text(
            isCreation
                ? Text("created")
                : Text("updated"),
          ),
        ),
      ],
    );
  }
}

This class I call it in a SnackBar as content (in the parent widget), and it shows it in the following example:

enter image description here

Code :

ScaffoldMessenger.of(context).showSnackBar(SnackBar(
   duration: Duration(seconds: 2),
   content: ActionSuccessSnackBar(
       name: "hello",
       isCreation: false,
     ),
   backgroundColor: Colors.green,
));

However, when I go to the main menu (pop) I get the following error:

enter image description here

Any idea about this problem? If I remove the class that I created and just put a text, it works, same if I put the row in the content without the class it works, but that is not what I want.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Daniel Roldán
  • 1,328
  • 3
  • 20

2 Answers2

2

Simply what is happening is you're using a context that is deactivated, let me explain it in this scenario; you are on your main screen, let's call it ScreenA, then you navigate to another screen, let's call this ScreenB. let's say there is a button in ScreenB that does the following:

onPressed: () {
   Navigator.of(context).pop();
   ScaffoldMessenger.of(context).showSnackBar...
}

what is happening here is, after you've popped from ScreenB, its context (which you've also used to show the snack bar), becomes invalid.

a simple solution I use is to use a Global Navigator key

simply, put this code where you initialize your MaterialApp:

class MyApp extends StatelessWidget {
  static GlobalKey<NavigatorState> navKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: navKey,

and when showing a snackbar:

final _context = MyApp.navKey.currentContext;
    if(_context!=null)
       ScaffoldMessenger.of(_context).showSnackBar...
Adnan
  • 906
  • 13
  • 30
0

I encounter a similar issue. In my case it was in a login page that redirecting to home screen.

In the loggin page i have a snackbar that display feedback to user ("can't loggin" or "loggin success" messages some stuff like this). The key point is you have to keep a reference on the context of the current page (using ScaffoldState).

This way the snackbar will correctly display even if the next screen is show to the user.

class _MyStatefulWidgetState extends State<LoginScreen> {
  TextEditingController nameController = TextEditingController();
  TextEditingController passwordController = TextEditingController();

  ....
  // add the state to get the current context
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();

... 
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<LoginModel>(
      create: (context) => serviceLocator<LoginModel>(),
      child: Consumer<LoginModel>(
          builder: (context, model, child) =>
              Scaffold(
                  key: _scaffoldKey, // here is the key, to keep reference on the context
                  body :
                  Form(
     

...

void connect(LoginModel model) async {
    var loginSuccess = await model.login(nameController.text,passwordController.text);
    if (loginSuccess) {
      // check context before showing snackbar
      BuildContext? currentContext = _scaffoldKey.currentContext;
      if(currentContext != null) {
        ScaffoldMessenger.of(currentContext).showSnackBar(
            const SnackBar(
              content: Text("successfully logged in !"),
              duration: Duration(seconds: 3),
            )
        );
      }
      // root to home (snackbar message will be correctly display on the next screen)
      Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => const HomeScreen()));
    }
    else {
      // snackbar error
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
            content: Text(model.errorMessage!)),
      );
    }
  }

}
Zhar
  • 3,330
  • 2
  • 24
  • 25