'Flutter Snackbar on screen initState

Three Questions:

  1. How to load snackbar in flutter in initState or when app loads the initial screen? I have the code below but it throws an error and doesn't load the screen text.
class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {

  @override
  void initState() {
    print('In Init State Stream Builder');
  
    _showSnackbar(context);
    
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text("Hello World"),
      ),
    );
  }

  void _showSnackbar(BuildContext ctx) {
    Scaffold.of(ctx).showSnackBar(
      SnackBar(
        content: ListTile(
          onTap: () {
            Scaffold.of(ctx).hideCurrentSnackBar();
          },
          subtitle: Text("and i'm a subtitle"),
          trailing: Icon(Icons.check),
        ),
        duration: Duration(
          days: 1,
        ),
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
        behavior: SnackBarBehavior.floating,
      ),
    );
  }
}

The above code throws an error when loading.



Solution 1:[1]

To initialise a Snackbar on initState(), either you put a delay or you can execute a function after the layout is built like this :

void initState() {
 super.initState();
WidgetsBinding.instance
    .addPostFrameCallback((_) => _scaffoldKey.currentState.showSnackBar(SnackBar(content: Text("Your message here..")));
}

Solution 2:[2]

I am going to answer the first question here. You have two problems here.

  1. In Flutter, you cannot call Scaffold.of(context) within the widget that has Scaffold inside the build method. Scaffold.of(context) has to always be called from a context that has a Scaffold as its ancestors.

  2. If you want to call showSnackbar inside initState, you have to call it inside a delayed function. The duration can be 0.

I have a simple example here to show a

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ChildWidget(),
    );
  }
}

class ChildWidget extends StatefulWidget {
  @override
  _ChildWidgetState createState() => _ChildWidgetState();
}

class _ChildWidgetState extends State<ChildWidget> {
  @override
  Widget build(BuildContext context) {
    return Container();
  }

  @override
  void initState() {
    Future<Null>.delayed(Duration.zero, () {
      _showSnackbar();
    });
    super.initState();
  }

  void _showSnackbar() {
    Scaffold.of(context).showSnackBar(SnackBar(content: Text('content')));
  }
}

Solution 3:[3]

In flutter context will be available only after build has been completed, You can use either Future or WidgetsBinding.instance.addPostFrameCallback or SchedulerBinding.instance.addPostFrameCallback.

But I hope you will get same result if you move your _showSnackbar(context); to build method like this.

  @override
  Widget build(BuildContext context) {
    _showSnackbar(context);
    return Scaffold(
      body: Center(
        child: Text("Hello World"),
      ),
    );
  }

Solution 4:[4]

instead of putting it inside the initState() put it in didChangeDependencies()

@override
  void didChangeDependencies () {
   print('In Init State Stream Builder');

   _showSnackbar(context);

   super.didChangeDependencies();
  }

Solution 5:[5]

This worked for me :)

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance!.addPostFrameCallback((_) {
      // do what you want here
      final snackBar = SnackBar(
        content: const Text('Yay! A SnackBar!'),
        action: SnackBarAction(
          label: 'Undo',
          onPressed: () {
            // Some code to undo the change.
          },
        ),
      );

      // Find the ScaffoldMessenger in the widget tree
      // and use it to show a SnackBar.
      ScaffoldMessenger.of(context).showSnackBar(snackBar);
    });

  }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Q.u.a.n.g L.
Solution 2 dshukertjr
Solution 3 Gunaseelan
Solution 4 javachipper
Solution 5 Sandeep Ks