I want to show SnackBar only once when the page is displayed. But we can not call showSnackBar in build method.
Is there a handler that called after build?
You could use a StatefulWidget and call showSnackBar in the initState of your State. You will need to add a short delay before triggering showSnackBar. Here is a code sample.
import 'dart:async'; import 'package:flutter/material.dart'; void main() { runApp(new MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( home: new HomePage(), ); } } class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return new Scaffold( floatingActionButton: new FloatingActionButton( child: new Icon(Icons.developer_board), onPressed: () { Navigator.of(context).push( new MaterialPageRoute(builder: (_) => new MySecondPage()), ); }, ), ); } } class MySecondPage extends StatelessWidget { @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text('Developer Mode'), ), body: new MySecondPageBody(), ); } } class MySecondPageBody extends StatefulWidget { @override State createState() => new MySecondPageBodyState(); } class MySecondPageBodyState extends State<MySecondPageBody> { @override void initState() { new Future<Null>.delayed(Duration.ZERO, () { Scaffold.of(context).showSnackBar( new SnackBar(content: new Text("You made it! Congrats.")), ); }); super.initState(); } @override Widget build(BuildContext context) { return new Center( child: new Text('You are now a developer.'), ); } } initState will be call before build. Scaffold has not been made yet?Using a StatelessWidget and scheduleMicrotask you can achieve it as well
import 'dart:async'; import 'package:flutter/material.dart'; class App extends StatelessWidget { final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(); App() { scheduleMicrotask(() => _scaffoldKey.currentState.showSnackBar(SnackBar( content: Text('Hey!'), ))); } @override Widget build(BuildContext ctx) { return Scaffold( key: _scaffoldKey, appBar: AppBar( title: Text('Look mum!'), ), body: Container()); } } @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); }); } You can also try to attach to addPostFrameCallback (https://api.flutter.dev/flutter/scheduler/SchedulerBinding/addPostFrameCallback.html)
SchedulerBinding.instance.addPostFrameCallback((_) { //show snackbar here });