Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter Access parent Scaffold from different dart file

Tags:

flutter

dart

I have this:

  final GlobalKey<ScaffoldState> _scaffoldkey = new GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 2,
      child: Scaffold(
        key: _scaffoldkey,
        drawer: Menu(),
        appBar: AppBar(
          title: Container(
            child: Text('Dashboard'),
          ),
          bottom: TabBar(
            tabs: <Widget>[
              ...
            ],
          ),
        ),
        body: TabBarView(
          children: <Widget>[
            ...
          ],
        ),
      ),
    );
  }
}

Now, the drawer: Menu() is imported from another menu.dart file, which looks like this:

class Menu extends StatelessWidget {

  final GlobalKey<ScaffoldState> drawerKey = new GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return new Drawer(
      key: drawerKey,
      child: new ListView(
        children: <Widget>[
          new ListTile(
            dense: true,
            title: new Text('My Text'),
            onTap: () {
              // On tap this, I want to show a snackbar.
              scaffoldKey.currentState.showSnackBar(showSnack('Error. Could not log out'));
            },
          ),
        ],
      ),
    );
  }
}

With the above approach, I get

NoSuchMethodError: The method 'showSnackBar' was called on null.

An easy solution is to tuck the entire menu.dart contents in the drawer: ... directly.

Another way I'm looking at is being able to reference the parent scaffold in order to display the snackbar.

How can one achieve that?

Why can't one even just call the snackbar from anywhere in Flutter and compulsorily it has to be done via the Scaffold? Just why?

like image 513
KhoPhi Avatar asked Jul 09 '18 20:07

KhoPhi


1 Answers

You should try to avoid using GlobalKey as much as possible; you're almost always better off using Scaffold.of to get the ScaffoldState. Since your menu is below the scaffold in the widget tree, Scaffold.of(context) will do what you want.

The reason what you're attempting to do doesn't work is that you are creating two seperate GlobalKeys - each of which is its own object. Think of them as global pointers - since you're creating two different ones, they point to different things. And the state should really be failing analysis since you're passing the wrong type into your Drawer's key field...

If you absolutely have to use GlobalKeys for some reason, you would be better off passing the instance created in your outer widget into your Menu class as a member i.e. this.scaffoldKey, but this isn't recommended.

Using Scaffold.of, this is what your code would look like in the onTap function:

onTap: () {
  // On tap this, I want to show a snackbar.
  Scaffold.of(context).showSnackBar(showSnack('Error. Could not log out'));
},
like image 109
rmtmckenzie Avatar answered Oct 22 '22 23:10

rmtmckenzie