A. Rokbi
A. Rokbi

Reputation: 603

How could use SnackBars within the Scaffold in stateless widget?

I have a class extends StatelessWidget. When try call SnackBars in Scaffold like:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          actions: <Widget>[
          IconButton(
            splashRadius: 18,
            icon: const Icon(Icons.thumb_up),
            tooltip: 'Like the app',
            onPressed: () {
              final SnackBar snackBar = SnackBar(
                duration: const Duration(seconds: 1),
                content: const Text('Registered as you like the application.'),
                action: SnackBarAction(
                  label: 'Undo',
                  onPressed: () {},
                ),
              );
              ScaffoldMessenger.of(context).showSnackBar(snackBar);
            },
          ),
        ],
        title: const Text('My Application'),),
        body: const Center(
        child: Text("Hello World!"),)
        );
     }
 }

when run the application show error like:

Exception has occurred. FlutterError (No ScaffoldMessenger widget found. MyApp widgets require a ScaffoldMessenger widget ancestor. The specific widget that could not find a ScaffoldMessenger ancestor was: MyApp The ancestors of this widget were: [root] Typically, the ScaffoldMessenger widget is introduced by the MaterialApp at the top of your application widget tree.)

Upvotes: 0

Views: 518

Answers (4)

A. Rokbi
A. Rokbi

Reputation: 603

I found the solution for the problem but first: why the error happened? It Fails because ScaffoldMessenger.of(context) doesn't find anything above this widget's context. the solution to use Builder class as follows:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            actions: <Widget>[

              Builder(
                builder: (BuildContext context) {
                  return IconButton(
                    splashRadius: 18,
                    icon: const Icon(Icons.thumb_up),
                    tooltip: 'Like the app',
                    onPressed: () {
                      final SnackBar snackBar = SnackBar(
                        duration: const Duration(seconds: 1),
                        content: const Text(
                            'Registered as you like the application.'),
                        action: SnackBarAction(
                          label: 'Undo',
                          onPressed: () {},
                        ),
                      );
                      ScaffoldMessenger.of(context).showSnackBar(snackBar);
                    },
                  );
                },
              ),
            ],
            title: const Text('My Application'),
          ),
          body: const Center(
            child: Text("Hello World!"),
          )),
    );
  }
}

Upvotes: 0

A. Rokbi
A. Rokbi

Reputation: 603

I found the answer from the youtube video as the following:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());
final _scaffoldkey = GlobalKey<ScaffoldMessengerState>();

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      scaffoldMessengerKey: _scaffoldkey,
      home: Scaffold(
        appBar: AppBar(
          actions: <Widget>[
            IconButton(
              splashRadius: 18,
              icon: const Icon(Icons.thumb_up),
              tooltip: 'Like the app',
              onPressed: () {
                final SnackBar snackBar = SnackBar(
                  duration: const Duration(seconds: 1),
                  content:
                      const Text('Registered as you like the application.'),
                  action: SnackBarAction(
                    label: 'Undo',
                    onPressed: () {},
                  ),
                );
                ScaffoldMessengerState? scaffold = _scaffoldkey.currentState;
                scaffold!.showSnackBar(snackBar);
              },
            ),
          ],
          title: const Text('My Application'),
        ),
        body: const Center(
          child: Text("Hello World!"),
        ),
      ),
    );
  }
}

Upvotes: 0

ajees
ajees

Reputation: 11

use this code

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  GlobalKey<ScaffoldMessengerState> key = GlobalKey<ScaffoldMessengerState>();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ScaffoldMessenger(
        key: key,
        child: Scaffold(
            appBar: AppBar(
              actions: <Widget>[
                IconButton(
                  splashRadius: 18,
                  icon: const Icon(Icons.thumb_up),
                  tooltip: 'Like the app',
                  onPressed: () {
                    final snackBar = SnackBar(
                      content: Text(
                        "message",
                        // style: Theme.of(context).textTheme.regularWhite14,
                      ),
                      duration: const Duration(seconds: 5),
                      action: SnackBarAction(
                        label: 'OK',
                        textColor: CustomColorScheme.whiteColor,
                        onPressed: () {},
                      ),
                    );
                    key.currentState!.showSnackBar(snackBar);
                  },
                ),
              ],
              title: const Text('My Application'),
            ),
            body: const Center(
              child: Text("Hello World!"),
            )),
      ),
    );
  }
}

Upvotes: 1

Ivo
Ivo

Reputation: 23164

Wrap your app in an MaterialApp, like

void main() => runApp(MaterialApp(home: MyApp()));

Upvotes: 1

Related Questions