前言
在日常 APP 开发过程中,经常会使用到 Toast 来弹出应用内的小通知来告知用户一些小情况。但 Flutter 中并没有带有类似 Toast 这样的工具类,翻了 StackOverflow 都是建议使用 SnackBar 来弹出提示。例如:
Scaffold.of(context).showSnackBar(SnackBar(content: Text('message')));复制代码
个人不太满意这样的实现方式。在巧合之下,我发现了 Overlay
这个类,于是诞生了借用 Overlay
来实现 toast 的想法。
项目的地址在
预览
先放两张效果图来展示最终效果
notification | toast |
---|---|
怎么使用
使用的方式很简单,引入包后简单调用即可。
//弹出toasttoast(context, '消息');//弹出notificationshowSimpleNotification(context, Text('消息'));复制代码
实现过程
整体实现的核心逻辑在 showOverlay(BuildContext, builder, ...)
中:
NotificationEntry showOverlay( BuildContext context, AnimatedOverlayWidgetBuilder builder, { bool autoDismiss = true, Curve curve}) { assert(autoDismiss != null); GlobalKeykey = GlobalKey(); //步骤1 创建OverlayEntry final entry = OverlayEntry(builder: (context) { return AnimatedOverlay( key: key, builder: builder, curve: curve, ); }); NotificationEntry notification = NotificationEntry(entry, key); //步骤2 将OverlayEntry添加到Overlay中 Overlay.of(context).insert(entry); if (autoDismiss) { Future.delayed(kNotificationDuration + kNotificationSlideDuration) .whenComplete(() { //ensure entry has been inserted into screen WidgetsBinding.instance .scheduleFrameCallback((_) => notification.dismiss()); }); } return notification;}复制代码
主要分为这么几个部分:
- 创建
OverlayEntry
。为了方便实现动画效果,我抽出了一个单独的 widget ——AnimatedOverlay
。 - 将
OverlayEntry
添加到Overlay
中。 - 如果 autoDismiss 设置为 true 的话,就在一段事件之后(kNotificationDuration + kNotificationSlideDuration),将
OverlayEntry
从Overlay
中移除。
弊端
使用 Overlay
来实现 Toast
效果很简便,但是有一个弊端:无法在后台弹出。
最后
如果大家有什么想法或者建议的话,可以直接在 Github 中提 issues 或者 PR,这样可以让库的可用性更高一些,谢谢大家。