How does Flutter display SnackBar correctly

  • 2021-12-12 09:49:09
  • OfStack

Directory Introduction Official example Error example Solution 1: Subcomponents of Scaffold are built through Builder Solution 2: Use GlobalKey to store ScaffoldStateFlutter to learn Github code repository

Brief introduction

The of method description of Scaffold in the official API document states that calling Scaffold. of method is in Build method of Scallfold subcomponent, that is, it cannot be directly called in build method of building Scaffold, otherwise an exception will be thrown.

Typical usage of the Scaffold.of function is to call it from within the build method of a child of a Scaffold.

Usually, to display an SnackBar, you need to build an Builder, which is called through context of Builder (reason)


Scallfold.of(context).showSnackBar(SnackBar(contenxt: Text(' This is 1 A SnackBar'));

Official example

Showing SnackBar, the official typical example code is as follows:


import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Code Sample for Scaffold.of.',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        body: MyScaffoldBody(),
        appBar: AppBar(title: Text('Scaffold.of Example')),
      ),
      color: Colors.white,
    );
  }
}

//  In Scaffold Subcomponent of the build Method can call the Scaffold.of Method 
class MyScaffoldBody extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: RaisedButton(
        child: Text('SHOW A SNACKBAR'),
        onPressed: () {
          Scaffold.of(context).showSnackBar(
            SnackBar(
              content: Text('Have a snack!'),
            ),
          );
        },
      ),
    );
  }
}

Error example

However, if called directly from the build method that builds Scallfold, an exception will be reported:


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

The error code is as follows:


import 'package:flutter/material.dart';

class ScaffoldSnackBarDemo extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: RaisedButton(
          child: Text('SHOW A SNACKBAR'),
          onPressed: () {
            /// Directly in Scallfold Adj. build Exceptions are thrown when used in the method 
            Scaffold.of(context).showSnackBar(
              SnackBar(
                content: Text('Have a snack!'),
              ),
            );
          },
        ),
      ),
      appBar: AppBar(title: Text('Scaffold.of Example')),
    );
  }
}

Solution 1: Subcomponents of Scaffold are built through Builder

At this time, either according to the official, the code that needs to display SnackBar will be separated from another custom subcomponent, and SnackBar will be displayed in the build method of the subcomponent, or Builder will be wrapped in the build method body of Scaffold, as shown below.


import 'package:flutter/material.dart';

class ScaffoldSnackBarDemo extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return Scaffold(
       /// Packaging outside subcomponents 1 Layer builder , let context Do not share 
      body: Builder(builder: (context) {
        return Center(
          child: RaisedButton(
            child: Text('SHOW A SNACKBAR'),
            onPressed: () {
              Scaffold.of(context).showSnackBar(
                SnackBar(
                  content: Text('Have a snack!'),
                ),
              );
            },
          ),
        );
      }),
      appBar: AppBar(title: Text('Scaffold.of Example')),
    );
  }
}

Solution 2: Use GlobalKey to store ScaffoldState


import 'package:flutter/material.dart';

class ScaffoldSnackBarDemo extends StatelessWidget {
  final _scallfoldKey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      /// Use GlobalKey Solve 
      key: _scallfoldKey,
      body: Center(
        child: RaisedButton(
          child: Text('SHOW A SNACKBAR'),
          onPressed: () {
            _scallfoldKey.currentState.showSnackBar(SnackBar(
              content: Text('Have a snack!'),
            ));
          },
        ),
      ),
      appBar: AppBar(title: Text('Scaffold.of Example')),
    );
  }
}

Flutter Learning Github Code Warehouse

https://github.com/AiguangLi/Flutter

The above is how Flutter correctly display SnackBar details, more about Flutter correctly display SnackBar information please pay attention to other related articles on this site!


Related articles: