Ramesh Kumar
Ramesh Kumar

Reputation: 197

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.

Upvotes: 5

Views: 3515

Answers (6)

The EasyLearn Academy
The EasyLearn Academy

Reputation: 927

 ScaffoldMessenger.of(context).showSnackBar(
  SnackBar(
    content: Text('this is an example of snackhar.'),
    action: SnackBarAction(
      label: 'Ok',
      onPressed: () {
        // Code to execute.
      },
    ),
  ),
);

Upvotes: 0

Sandeep Ks
Sandeep Ks

Reputation: 544

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);
    });

  }

Upvotes: 0

javachipper
javachipper

Reputation: 537

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

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

   _showSnackbar(context);

   super.didChangeDependencies();
  }

Upvotes: 0

Gunaseelan
Gunaseelan

Reputation: 15535

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"),
      ),
    );
  }

Upvotes: 0

Q.u.a.n.g L.
Q.u.a.n.g L.

Reputation: 1614

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..")));
}

Upvotes: 7

dshukertjr
dshukertjr

Reputation: 18770

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')));
  }
}

Upvotes: 5

Related Questions