9

i want create SnackBar for reusable(globally)

i already created but its only for 1 page , i don't know how to create reusable.

below code:

import 'package:flutter/material.dart';

class SnackBarMain extends StatefulWidget {
  @override
  _SnackBarMainState createState() => _SnackBarMainState();
}

class _SnackBarMainState extends State<SnackBarMain> {
  final globalKey = GlobalKey<ScaffoldState>();
  String title = 'SnackBar';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: globalKey,
      resizeToAvoidBottomPadding: false,
      appBar: AppBar(
        centerTitle: true,
        title: Text(title),
      ),
      body: Center(
        child: RaisedButton(
          shape: new RoundedRectangleBorder(
              borderRadius: new BorderRadius.circular(18.0),
              side: BorderSide(color: Colors.purple)),
          onPressed: () => snackBarMsg(context),
          color: Colors.purple,
          textColor: Colors.white,
          child: Text("SnackBar",
              style: TextStyle(fontSize: 18)),
        ),
      ),
    );
  }

snackBarMsg(BuildContext context) {
    final sb = SnackBar(
      elevation: 0.0,
      //behavior: SnackBarBehavior.floating,
      content: Text('SnackBar Bottom Message'),
      duration: new Duration(seconds: 5000000),
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.only(
            topLeft: Radius.circular(16.0), topRight: Radius.circular(16.0)),
      ),
      //backgroundColor: Colors.redAccent,
      action: SnackBarAction(
        textColor: Color(0xFFFAF2FB),
        label: 'OK',
        onPressed: () {},
      ),
    );
    globalKey.currentState.showSnackBar(sb);
  }
}

so any one please give me example for this

MohammedAli
  • 2,361
  • 2
  • 19
  • 36

6 Answers6

18

You can have a class that has a static method show() which receives the context and shows a snackbar. Check te code below.

class GlobalSnackBar {
  final String message;

  const GlobalSnackBar({
    @required this.message,
  });

  static show(
    BuildContext context,
    String message,
  ) {
    Scaffold.of(context).showSnackBar(
      SnackBar(
        elevation: 0.0,
        //behavior: SnackBarBehavior.floating,
        content: Text(message),
        duration: new Duration(seconds: 5000000),
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.only(
              topLeft: Radius.circular(16.0), topRight: Radius.circular(16.0)),
        ),
        //backgroundColor: Colors.redAccent,
        action: SnackBarAction(
          textColor: Color(0xFFFAF2FB),
          label: 'OK',
          onPressed: () {},
        ),
      ),
    );
  }
}

And you can call it from anywhere like this:

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return RaisedButton(
      child: Text('SHOW Snackbar'),
      onPressed: () => GlobalSnackBar.show(context, 'Test'),
    );
  }
}

Remember that the context you pass to show() method has to be a descendant from Scaffold in order to show the SnackBar

Sebastian
  • 3,666
  • 2
  • 19
  • 32
16

Just create a public class and put your custom functions inside, here you go for example:

//Custom class in project directory
class CustomWidgets {
 CustomWidgets._();
 static buildErrorSnackbar(BuildContext context, String message) {
  Scaffold.of(context)
     .showSnackBar(
    SnackBar(
      content: Text("$message"),
    ),
  );
 }
}

 // This is any page in your project

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
     backgroundColor: Colors.white,
      //        Always create body with Builder method so you can 
      //        get exact context to pass
      body: Builder(
      builder: (context) =>
          Center(
              child: RaisedButton(
              color: Colors.pink,
              textColor: Colors.white,
              onPressed: (){
                CustomWidgets.buildErrorSnackbar(context,"Your message here");
              },
              child: Text('Display SnackBar'),
          ),
         ),
     ),
  );
 }
}
Mateen
  • 418
  • 1
  • 3
  • 12
3

Scaffold.of(context).showSnackbar is deprecated now. You should use ScaffoldMessenger instead. Use like this:-

ScaffoldMessenger.of(context).showSnackBar(SnackBar(
          content: Text('User Successfully Logged In...'),
        ));
Rahul Kushwaha
  • 5,473
  • 3
  • 26
  • 30
0

You can use the Snackbar you have already defined to reuse it everywhere by putting it in a public folder, that can be accessed from anywhere in your app. You don't need to enclose it inside a widget or a class. Then, you can show it by calling Scaffold.of(context).showSnackBar(...). For that, you will need to pass the current BuildContext, of course. This way, as long as the context from which you call showSnackBar has a parent Scaffold, the snackbar will be shown for your current page, and you can do this from anywhere.

Consider this example, that I myself have used in the past:

  void buildErrorSnackbar(BuildContext context) {
    Scaffold.of(context).showSnackBar(
      SnackBar(
        content: Text("Oops! Something went wrong."),
      ),
    );
  }
drogel
  • 2,567
  • 2
  • 13
  • 22
  • bro how to call snackbar in another Page? – MohammedAli Feb 20 '20 at 12:07
  • You can declare your own `buildSnackbar` method anywhere, you don't need to enclose it in a class. This way you can call if from anywhere, you just need to pass the corresponding `BuildContext`. – drogel Feb 20 '20 at 13:48
0

you can create a public snackbar class like this

//=========================================================
// PUBLIC SNACK BAR WIDGET
//=========================================================
class PublicSnackBar extends SnackBar {
  const PublicSnackBar({Key? key, required super.content}) : super(key: key);
}

and call it in any pages or files in the project, tho I am using public context here.

 ScaffoldMessenger.of(navigatorKey.currentContext as BuildContext)
        .showSnackBar(PublicSnackBar(content: Text('$result')));

this is my public context, just in case you were wondering,

//=========================================================================
// NAVIGATING WITH OUT CONTEXT
//=========================================================================
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
0

I suggest you try to build a Extension like that then your problem will be solve if you try to create a widget for that then you face some problems so try to use extension Output will be look like this

 extension SnackBarExt on BuildContext {
  void fluidSnackBar(String message) {
    ScaffoldMessenger.of(this)
      ..hideCurrentSnackBar()
      ..showSnackBar(SnackBar(
          behavior: SnackBarBehavior.floating,
          margin: const EdgeInsets.all(Dimension.d4),
          shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(Dimension.d1)),
          backgroundColor: secondarySwatch.shade800,
          duration: const Duration(seconds: 4),
          padding: const EdgeInsets.symmetric(
              vertical: Dimension.d3, horizontal: Dimension.d4),
          content: Text(message,
              style: fluidTextStyles.caption.colored(secondarySwatch.shade25),
              overflow: TextOverflow.ellipsis)));
  }
Anuj Kumar
  • 21
  • 3