11

I want to create a Snackbar, that looks like an image below, Google has created. Something like this:Google Material Sesifn Snackbar I wanted to start creating one, but I don't have an idea about it, how should I start or how should I customize the Snackbar. I don't want to use flutter toast plugin. I want to create my own Snackbar. It would be great if somebody guides me on this

K K
  • 952
  • 9
  • 25

5 Answers5

17

First of all, based on your screenshot, maybe this is already supported by SnackBarBehavior, just pass the snackbar constructor behavior: SnackBarBehavior.floating, like this:

SnackBar(behavior: SnackBarBehavior.floating, content: ...)

If this is still not good enough, the best way to go about it is by starting with the SnackBar widget and customizing it. Though the widget's constructor parameters make the widget quite flexible, the SnackBar widget does not let you modify every little detail of it.

For example, I wanted to remove some padding in the snack bar and add some borders on the top, and at the time of this writing, this wasn't possible.

You should not modify directly the snack_bar.dart as it'll modify your local copy Flutter. Modifying snack_bar.dart directly has a couple of disadvantages:

  1. All your local Flutter projects will have these modifications.
  2. If you are in a team, nobody else will have these customizations.
  3. If you use a "standard" CI/CD pipeline -as you only modified your local copy of Flutter-, the built apps will not have these customizations, nor does the released apps, obviously.
  4. Upgrading Flutter (or changing channels) could be more difficult, as Flutter is using git (branches, commits) in the background for upgrading

The best solution for adding any complicated tweaks, implementing any customization to the SnackBar widget (apart from its public interface, of course) is to implement it.

class BetterSnackBar extends StatelessWidget implements SnackBar {
  Widget build(BuildContext context) {
     // Tweak the build method for maximum customization
  }

  // rest of the class, you can just copy-paste it
  // from SnackBar, if you want to make sure you support
  // everything the original snack bar supports
}

This way, you can still use your custom BetterSnackBar widget like the original for example, for showing it using the scaffold: Scaffold.of(context).showSnackBar(betterSnackBar);.

This solution also leaves your local Flutter copy untouched (other projects won't be affected by it, you can easily switch between Flutter channels and upgrade your Flutter version on your computer), meaning you can version control your project's BetterSnackBar (CI works, co-workers will see the changes).

Vince Varga
  • 6,101
  • 6
  • 43
  • 60
  • Worth noting that `SnackBarBehavior` is not avaible in the latest stable build, so unless you want to move to an unstable channel, you'll need to go with the `BetterSnackBar` solution anyway. – Warren Jun 21 '19 at 13:21
  • I don't know if in 2019 SnackBar was built differently but in 2022 this method doesn't work anymore. Or rather, implementig SnackBar asks to implement also the createState method because the original SnackBar is in fact a StatefulWidget and the code goes into the original build method. I showed the issue in this question: https://stackoverflow.com/questions/71328854/can-i-override-materialbanner-widget-to-change-its-height – Marco Rossi Mar 02 '22 at 21:51
2

If you want to achieve the floating look, with the nice animation sliding up from the bottom, you can do it manually, with a some customizations to the standard SnackBar implementation, without having to edit the source code of Flutter:

final snackBar = SnackBar(
  backgroundColor: Colors.transparent,
  elevation: 0,
  content: Container(
      padding: const EdgeInsets.all(8),
      decoration: BoxDecoration(
        color: Colors.greenAccent,
        border: Border.all(color: Colors.green, width: 3),
        boxShadow: const [
          BoxShadow(
            color: Color(0x19000000),
            spreadRadius: 2.0,
            blurRadius: 8.0,
            offset: Offset(2, 4),
          )
        ],
        borderRadius: BorderRadius.circular(4),
      ),
      child: Row(
        children: [
          const Icon(Icons.favorite, color: Colors.green ),
          const Padding(
            padding: EdgeInsets.only(left: 8.0),
            child: Text('Yay! A SnackBar!\nYou did great!', style: TextStyle(color: Colors.green)),
          ),
          const Spacer(),
          TextButton(onPressed: () => debugPrint("Undid"), child: Text("Undo"))
        ],
      )
  ),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
Jared Anderton
  • 826
  • 9
  • 12
1

This wouldn't be a snackbar but it can work the same.

1) Create a view using LinearLayout, Relative, or Constraint that looks like the snack bar insdie of the page you want it on.

2) set the Visibility to Gone, or Invisible.

3) add onCLickListener to a button to make the Snackbar(the layout you just made) visible when the button is clicked.

Kristofer
  • 809
  • 9
  • 24
1

If you want to show a fully customized snackBar then I hope my this answer is going to help you.

1: Add this package in your pubspec.yaml file ( smart_snackbars: ^1.0.0 )
2: import 'package:smart_snackbars/smart_snackbars.dart'; in your required file.

For example

You want to show a snackBar on button click then paste the following code in your callback function

callback: () {
            SmartSnackBars.showCustomSnackBar(
                context: context,
              duration: const Duration(milliseconds: 1000),
              animateFrom: AnimateFrom.fromTop,
              distanceToTravel: 0.0,
              outerPadding: const EdgeInsets.all(0),
              child: Container(
                margin: EdgeInsets.symmetric(horizontal: 10.w,vertical: 10.h),
                padding: EdgeInsets.fromLTRB(16.w, 10.h, 23.w, 10.h),
                decoration: BoxDecoration(
                  color: const Color.fromRGBO(0, 23, 90, 1),
                  borderRadius: BorderRadius.circular(10.r)
                ),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Row(
                      children: [
                        Image.asset("assets/images/success2.png", height: 16.h,),
                        8.horizontalSpace,
                        LabelTextWidget(
                            text: "Your changes have been saved",
                            fontWeight: FontWeight.w400,
                            fontSize: 12.sp,
                            textColor: Colors.white,
                        ),
                      ],
                    ),
                    LabelTextWidget(
                      text: "Close",
                      fontWeight: FontWeight.w600,
                      fontSize: 12.sp,
                      textColor: Colors.white,
                    ),

                  ],
                ),
              ),
            );
          },

Result:

This is how you can make a fully customised snackBar

Ijlal Hussain
  • 390
  • 1
  • 5
  • 16
0

EDIT: Warning!!!!!!! I check it and it change for all your projects, so I think it is not a really good option

Hello I have been trying doing the same as you, and the way that i found and can be helpful is edit the main snack_bar.dart file. You can access it by holding the control key and clicking on a Snackbar widget in the code.

After that just add this at the begining "import 'package:flutter/material.dart';" and change this:

      child: Material(
      elevation: 6.0,
      color: _kSnackBackground,
      child: Theme(
        data: darkTheme,
        child: mediaQueryData.accessibleNavigation ? snackbar : FadeTransition(
          opacity: fadeAnimation,
          child: snackbar,
        ),
      ),
    ),

for this:

      child: Card(
      elevation: 6.0,
      color: _kSnackBackground,
      child: Theme(
        data: darkTheme,
        child: mediaQueryData.accessibleNavigation ? snackbar : FadeTransition(
          opacity: fadeAnimation,
          child: snackbar,
        ),
      ),
    ),

And the result when you implement your snackbar going to be the next: enter image description here

JeCr
  • 79
  • 1
  • 1
  • 6
  • It's a local change, it will not persist if you write projects not locally. You could fork flutter repository and work with it... Anyway, this answer is very low quality and comes from total lack of understanding – Olga Jun 06 '23 at 13:25