在平常 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