4

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?

najeira
  • 3,133
  • 2
  • 19
  • 21

4 Answers4

8

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.'),
    );
  }
}
Collin Jackson
  • 110,240
  • 31
  • 221
  • 152
4

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());
  }
}
AleC
  • 472
  • 6
  • 8
0

You can also try to attach to addPostFrameCallback (https://api.flutter.dev/flutter/scheduler/SchedulerBinding/addPostFrameCallback.html)

SchedulerBinding.instance.addPostFrameCallback((_) {
    //show snackbar here
  });
Qiong Wu
  • 1,504
  • 1
  • 15
  • 27
0
@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);
    });

  }
Sandeep Ks
  • 504
  • 3
  • 13