在平常 APP 开发过程当中,常常会使用到 Toast 来弹出应用内的小通知来告知用户一些小状况。但 Flutter 中并无带有相似 Toast 这样的工具类,翻了 StackOverflow 都是建议使用 SnackBar 来弹出提示。例如:git
Scaffold.of(context).showSnackBar(SnackBar(content: Text('message')));
复制代码
我的不太满意这样的实现方式。在巧合之下,我发现了 Overlay
这个类,因而诞生了借用 Overlay
来实现 toast 的想法。github
项目的地址在 github.com/boyan01/ove…ide
先放两张效果图来展现最终效果工具
notification | toast |
---|---|
![]() |
![]() |
使用的方式很简单,引入包后简单调用便可。动画
//弹出toast
toast(context, '消息');
//弹出notification
showSimpleNotification(context, Text('消息'));
复制代码
总体实现的核心逻辑在 showOverlay(BuildContext, builder, ...)
中:ui
NotificationEntry showOverlay(
BuildContext context, AnimatedOverlayWidgetBuilder builder,
{bool autoDismiss = true, Curve curve}) {
assert(autoDismiss != null);
GlobalKey<AnimatedOverlayState> key = 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;
}
复制代码
主要分为这么几个部分:spa
OverlayEntry
。为了方便实现动画效果,我抽出了一个单独的 widget —— AnimatedOverlay
。OverlayEntry
添加到 Overlay
中。OverlayEntry
从 Overlay
中移除。使用 Overlay
来实现 Toast
效果很简便,可是有一个弊端:没法在后台弹出。code
若是你们有什么想法或者建议的话,能够直接在 Github 中提 issues 或者 PR,这样可让库的可用性更高一些,谢谢你们。cdn