【问题标题】:Flutter - Create own snackbar designFlutter - 创建自己的小吃店设计
【发布时间】:2025-12-05 01:20:04
【问题描述】:

我想创建一个Snackbar,如下图所示,Google 已创建。像这样的东西: 我想开始创建一个,但我不知道应该如何开始或如何自定义Snackbar。我不想使用颤振吐司插件。我想创建自己的Snackbar。如果有人指导我,那就太好了

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    首先,根据你的截图,可能SnackBarBehavior已经支持这个了,只需通过snackbar构造函数behavior: SnackBarBehavior.floating,像这样:

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

    如果这仍然不够好,最好的方法是从 SnackBar 小部件开始并对其进行自定义。尽管小部件的构造函数参数使小部件非常灵活,但SnackBar 小部件不允许您修改它的每个小细节。

    例如,我想删除小吃店的一些填充并在顶部添加一些边框,而在撰写本文时,这是不可能的。

    您不应该直接修改snack_bar.dart,因为它会修改您的本地副本 Flutter。 直接修改snack_bar.dart有几个缺点

    1. 您的所有本地 Flutter 项目都将进行这些修改。
    2. 如果您在团队中,其他人将不会拥有这些自定义设置。
    3. 如果您使用“标准”CI/CD 管道(因为您只修改了 Flutter 的本地副本),则构建的应用程序将没有这些自定义项,显然发布的应用程序也没有。
    4. 升级 Flutter(或更改通道)可能会更加困难,因为 Flutter 在后台使用 git(分支、提交)进行升级

    添加任何复杂调整、对SnackBar 小部件(当然,除了它的公共界面之外)实现任何自定义的最佳解决方案是implement

    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
    }
    

    这样,您仍然可以像原来一样使用您的自定义 BetterSnackBar 小部件,例如,使用脚手架显示它:Scaffold.of(context).showSnackBar(betterSnackBar);

    这个解决方案也不会影响你本地的 Flutter 副本(其他项目不会受到它的影响,你可以轻松地在 Flutter 通道之间切换并在你的计算机上升级你的 Flutter 版本),这意味着你可以对你的项目的BetterSnackBar进行版本控制(CI 有效,同事会看到变化)。

    【讨论】:

    • 值得注意的是,SnackBarBehavior 在最新的稳定版本中不可用,因此除非您想移动到不稳定的频道,否则无论如何您都需要使用BetterSnackBar 解决方案。跨度>
    • 我不知道 2019 年 SnackBar 的构建方式是否有所不同,但在 2022 年这种方法不再适用。或者更确切地说,implementig SnackBar 要求也实现 createState 方法,因为原始 SnackBar 实际上是一个 StatefulWidget 并且代码进入原始构建方法。我在这个问题中展示了这个问题:*.com/questions/71328854/…
    【解决方案2】:

    如果你想实现浮动的外观,漂亮的动画从底部向上滑动,你可以手动完成,对标准的 SnackBar 实现进行一些自定义,而无需编辑 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);
    

    【讨论】:

      【解决方案3】:

      这不会是一个小吃店,但它可以工作。

      1) 使用 LinearLayout、Relative 或 Constraint 创建一个看起来像您想要的页面的小吃店insdie 的视图。

      2) 将可见性设置为消失或不可见。

      3) 将 onCLickListener 添加到按钮中,以在单击按钮时使 Snackbar(您刚刚制作的布局)可见。

      【讨论】:

      • 你确定这个答案是针对 Flutter 的吗?
      • 这仅用于android目的而不是用于颤振
      • 其实它是为 android 设计的,但这个想法还不错。你可以只使用一个 AnimatedPositioned 小部件,然后当你想显示“snackbar”时,只需更改它的位置参数,反之亦然
      • 他只是给出了一个想法,我们可以用flutter的小部件轻松适应它
      【解决方案4】:

      编辑:警告!!!!!!!我检查了它,它会为你所有的项目而改变,所以我认为这不是一个很好的选择

      你好,我一直在尝试和你做同样的事情,我发现并且可以提供帮助的方法是编辑主要的snack_bar.dart 文件。您可以通过按住控制键并单击代码中的 Snackbar 小部件来访问它。

      之后只需在开头添加这个“import 'package:flutter/material.dart';”并改变这个:

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

      为此:

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

      当你实现你的小吃店时,结果将是下一个:

      【讨论】: