flutterdartsnackbarscaffold

Scaffold.of() called with a context that does not contain a Scaffold


As you can see, my button is inside the Scaffold's body. But I get this exception:

Scaffold.of() called with a context that does not contain a Scaffold.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('SnackBar Playground'),
      ),
      body: Center(
        child: RaisedButton(
          color: Colors.pink,
          textColor: Colors.white,
          onPressed: _displaySnackBar(context),
          child: Text('Display SnackBar'),
        ),
      ),
    );
  }
}

_displaySnackBar(BuildContext context) {
  final snackBar = SnackBar(content: Text('Are you talkin\' to me?'));
  Scaffold.of(context).showSnackBar(snackBar);
}

EDIT:

I found another solution to this problem. If we give the Scaffold a key which is the GlobalKey<ScaffoldState>, we can display the SnackBar as following without the need to wrap our body within the Builder widget. The widget which returns the Scaffold should be a Stateful widget though.

 _scaffoldKey.currentState.showSnackBar(snackbar); 

Solution

  • This exception happens because you are using the context of the widget that instantiated Scaffold. Not the context of a child of Scaffold.

    You can solve this by just using a different context :

    Scaffold(
        appBar: AppBar(
            title: Text('SnackBar Playground'),
        ),
        body: Builder(
            builder: (context) => 
                Center(
                child: RaisedButton(
                color: Colors.pink,
                textColor: Colors.white,
                onPressed: () => _displaySnackBar(context),
                child: Text('Display SnackBar'),
                ),
            ),
        ),
    );
    

    Note that while we're using Builder here, this is not the only way to obtain a different BuildContext.

    It is also possible to extract the subtree into a different Widget (usually using extract widget refactor)