SnackBar 是一个常见的底部消息弹框
1. SnackBar
  const SnackBar({
    Key? key,
    required this.content,
    this.backgroundColor,
    this.elevation,
    this.margin,
    this.padding,
    this.width,
    this.shape,
    this.behavior,
    this.action,
    this.duration = _snackBarDisplayDuration,
    this.animation,
    this.onVisible,
    this.dismissDirection = DismissDirection.down,
  })
SnackBar属性
| SnackBar属性 | 介绍 | 
|---|---|
| content | @required 左侧内容 Widget | 
| backgroundColor | 背景色 | 
| elevation | 阴影高度 | 
| padding | 内边距 | 
| margin | 外边距 不能和width 一起设置,behavior 设置为SnackBarBehavior.fixed时,不能设置margin | 
| width | SnackBar 宽度 不能和margin 一起设置,behavior 设置为SnackBarBehavior.fixed时,不能设置width | 
| shape | 形状 ShapeBorder | 
| behavior | SnackBarBehavior.fixed 是贴合屏幕边框的,SnackBarBehavior.floating 是悬浮出来的一个弹框 | 
| action | SnackBarAction,右侧事件按钮 | 
| duration | 弹框展示时长,默认为 Duration(milliseconds: 4000) | 
| animation | 动画效果,没啥太大用,使用 showSnackBar,会被自带动画替换 | 
| onVisible | SnackBar 展示在屏幕上时的回调函数 | 
| dismissDirection | SnackBar 消失方向 默认 DismissDirection.down | 
2. SnackBarAction
  const SnackBarAction({
    Key? key,
    this.textColor,
    this.disabledTextColor,
    required this.label,
    required this.onPressed,
  })
SnackBarAction属性
| SnackBarAction属性 | 介绍 | 
|---|---|
| textColor | 字体颜色 | 
| disabledTextColor | 不可用时字体颜色 | 
| label | 事件文字 | 
| onPressed | @required 点击事件 | 
3. 实例
示例1
  SnackBar _baseSnackBar1() {
    return SnackBar(
      content: Text("SnackBar 是一个常见的底部消息弹框。"), // 左侧内容 Widget
      backgroundColor: Colors.cyan[200], // 背景色
      elevation: 10, // 阴影高度
      shape:
          RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), // 形状
      padding: EdgeInsets.all(8), // 内边距
      // margin: EdgeInsets.all(8), // 外边距 不能和width 一起设置,behavior 设置为SnackBarBehavior.fixed时,不能设置margin
      // width: 300, //SnackBar 宽度 不能和margin 一起设置,behavior 设置为SnackBarBehavior.fixed时,不能设置width
      behavior: SnackBarBehavior
          .fixed, // SnackBarBehavior.fixed 是贴合屏幕边框的,SnackBarBehavior.floating 是悬浮出来的一个弹框
      // SnackBarAction,右侧事件按钮
      action: SnackBarAction(
        textColor: Colors.blue[400],
        disabledTextColor: Colors.grey[400],
        onPressed: () {},
        label: "关闭",
      ),
      duration: Duration(milliseconds: 4000), // 弹框展示时长
      // SnackBar 展示在屏幕上时的回调函数
      onVisible: () {},
      dismissDirection: DismissDirection.down, // 消失方向 默认 DismissDirection.down
    );
  }

image.png
示例2
  SnackBar _baseSnackBar2() {
    return SnackBar(
      content: Text(
          "Flutter是Google开源的构建用户界面(UI)工具包,帮助开发者通过一套代码库高效构建多平台精美应用,支持移动、Web、桌面和嵌入式平台。 [5]  Flutter 开源、免费,拥有宽松的开源协议,适合商业项目。Flutter已推出稳定的2.0版本。"),
      backgroundColor: Colors.amber,
      behavior: SnackBarBehavior.floating,
      margin: EdgeInsets.all(12),
      padding: EdgeInsets.all(8),
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
      duration: Duration(milliseconds: 5000),
      onVisible: () {
        print("onVisible");
      },
      dismissDirection: DismissDirection.up,
      elevation: 10.0,
      action: SnackBarAction(
        label: "OK",
        onPressed: () {
          print("SnackBarAction Clicked");
        },
        textColor: Colors.red[200],
      ),
    );
  }

image.png
示例3
  SnackBar _customContentSnackBar() {
    return SnackBar(
      content: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          CircleAvatar(
            backgroundImage: AssetImage("assets/images/4.jpeg"),
            radius: 40,
          ),
          SizedBox(width: 8),
          Expanded(
            child: Text(
                "Flutter是Google开源的构建用户界面(UI)工具包,帮助开发者通过一套代码库高效构建多平台精美应用,支持移动、Web、桌面和嵌入式平台。 [5]  Flutter 开源、免费,拥有宽松的开源协议,适合商业项目。Flutter已推出稳定的2.0版本。"),
          ),
        ],
      ),
      behavior: SnackBarBehavior.floating,
      margin: EdgeInsets.all(12),
      padding: EdgeInsets.all(8),
      action: SnackBarAction(
        label: "OK",
        onPressed: () {},
        textColor: Colors.red,
      ),
      backgroundColor: Colors.cyan[200],
      elevation: 8,
    );
  }

image.png
4. SnackBar 进阶
在SnackBar的使用过程中, 我们会发现一个问题,当我们连续点击不同弹框时,并不会立即弹出下一个,而是按照 duration 展示每一个 SnackBar,如果大量调用,就会一直在最下方等待弹出,这是肯定没法接受的。因而,我们需要取消上一个弹框
取消弹框有以下三种方式
ScaffoldMessenger.of(context).clearSnackBars();
ScaffoldMessenger.of(context).removeCurrentSnackBar();
ScaffoldMessenger.of(context).hideCurrentSnackBar();
所以建议这么使用,showSnackBar 之前,先隐藏当前 SnackBar。
  ScaffoldMessenger.of(context).clearSnackBars();
  ScaffoldMessenger.of(context)
      .showSnackBar(_baseSnackBar1());
5. Demo
class MSSnackBarRoute extends StatelessWidget {
  const MSSnackBarRoute({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("MSSnackBarRoute")),
      body: SingleChildScrollView(
        child: Center(
          child: Builder(builder: (context) {
            return Column(
              children: [
                ElevatedButton(
                  onPressed: () {
                    // ScaffoldMessenger.of(context).clearSnackBars();
                    // ScaffoldMessenger.of(context).removeCurrentSnackBar();
                    // ScaffoldMessenger.of(context).hideCurrentSnackBar();
                    ScaffoldMessenger.of(context).clearSnackBars();
                    ScaffoldMessenger.of(context)
                        .showSnackBar(_baseSnackBar1());
                  },
                  child: Text("SnackBar 1"),
                ),
                ElevatedButton(
                  onPressed: () {
                    ScaffoldMessenger.of(context).clearSnackBars();
                    ScaffoldMessenger.of(context)
                        .showSnackBar(_baseSnackBar2());
                  },
                  child: Text("SnackBar 2"),
                ),
                ElevatedButton(
                  onPressed: () {
                    ScaffoldMessenger.of(context).clearSnackBars();
                    ScaffoldMessenger.of(context)
                        .showSnackBar(_customContentSnackBar());
                  },
                  child: Text("SnackBar 3"),
                ),
              ],
            );
          }),
        ),
      ),
    );
  }
  SnackBar _baseSnackBar1() {
    return SnackBar(
      content: Text("SnackBar 是一个常见的底部消息弹框。"), // 左侧内容 Widget
      backgroundColor: Colors.cyan[200], // 背景色
      elevation: 10, // 阴影高度
      shape:
          RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), // 形状
      padding: EdgeInsets.all(8), // 内边距
      // margin: EdgeInsets.all(8), // 外边距 不能和width 一起设置,behavior 设置为SnackBarBehavior.fixed时,不能设置margin
      // width: 300, //SnackBar 宽度 不能和margin 一起设置,behavior 设置为SnackBarBehavior.fixed时,不能设置width
      behavior: SnackBarBehavior
          .fixed, // SnackBarBehavior.fixed 是贴合屏幕边框的,SnackBarBehavior.floating 是悬浮出来的一个弹框
      // SnackBarAction,右侧事件按钮
      action: SnackBarAction(
        textColor: Colors.blue[400],
        disabledTextColor: Colors.grey[400],
        onPressed: () {},
        label: "关闭",
      ),
      duration: Duration(milliseconds: 4000), // 弹框展示时长
      // SnackBar 展示在屏幕上时的回调函数
      onVisible: () {},
      dismissDirection: DismissDirection.down, // 消失方向 默认 DismissDirection.down
    );
  }
  SnackBar _baseSnackBar2() {
    return SnackBar(
      content: Text(
          "Flutter是Google开源的构建用户界面(UI)工具包,帮助开发者通过一套代码库高效构建多平台精美应用,支持移动、Web、桌面和嵌入式平台。 [5]  Flutter 开源、免费,拥有宽松的开源协议,适合商业项目。Flutter已推出稳定的2.0版本。"),
      backgroundColor: Colors.amber,
      behavior: SnackBarBehavior.floating,
      margin: EdgeInsets.all(12),
      padding: EdgeInsets.all(8),
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
      duration: Duration(milliseconds: 5000),
      onVisible: () {
        print("onVisible");
      },
      dismissDirection: DismissDirection.up,
      elevation: 10.0,
      action: SnackBarAction(
        label: "OK",
        onPressed: () {
          print("SnackBarAction Clicked");
        },
        textColor: Colors.red[200],
      ),
    );
  }
  SnackBar _customContentSnackBar() {
    return SnackBar(
      content: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          CircleAvatar(
            backgroundImage: AssetImage("assets/images/4.jpeg"),
            radius: 40,
          ),
          SizedBox(width: 8),
          Expanded(
            child: Text(
                "Flutter是Google开源的构建用户界面(UI)工具包,帮助开发者通过一套代码库高效构建多平台精美应用,支持移动、Web、桌面和嵌入式平台。 [5]  Flutter 开源、免费,拥有宽松的开源协议,适合商业项目。Flutter已推出稳定的2.0版本。"),
          ),
        ],
      ),
      behavior: SnackBarBehavior.floating,
      margin: EdgeInsets.all(12),
      padding: EdgeInsets.all(8),
      action: SnackBarAction(
        label: "OK",
        onPressed: () {},
        textColor: Colors.red,
      ),
      backgroundColor: Colors.cyan[200],
      elevation: 8,
    );
  }
}

135.gif