现有的Toast库都太重了。写了一堆的代码,这个才是最正确,最简单的。
看一下Overlay的注释:
/// A [Stack] of entries that can be managed independently.
一个stack控件,可以管理依赖它的entries
///
/// Overlays let independent child widgets "float" visual elements on top of
/// other widgets by inserting them into the overlay's [Stack]. The overlay lets
/// each of these widgets manage their participation in the overlay using
/// [OverlayEntry] objects.
Overlays通过把子widget插入到overlay的stack里面, 让依赖它的子widget可以浮在其它的可见元素上面。OverlayEntry可以管理漂浮的widgets。(一个OverlayEntry就是一个层)
///
/// Although you can create an [Overlay] directly, it's most common to use the
/// overlay created by the [Navigator] in a [WidgetsApp] or a [MaterialApp]. The
/// navigator uses its overlay to manage the visual appearance of its routes.
///
虽然我们可以自己创建一个Overlay,但是更通常的做法是,使用MaterialApp或者WidgetsApp中Navigator对象创建的Overlay. navigator使用overlay来管理可见的路由。(查看一下Navigator的源码,里面是返回了一个Overlay的,我们可以直接在这个Overlay中插入OverlayEntry来制作类似Toast,Loaing这样的widgets)
/// See also:
///
/// * [OverlayEntry].
/// * [OverlayState].
/// * [WidgetsApp].
/// * [MaterialApp].
下面是一个简单的Toast。Global.context是我自己定义的全局对象,在页面创建的时候保存了BuildContext, 这样在一些地方可以方便调用。也可以不保存,方法变成这样:
static void show(BuildContext context, String message, {int duration})
class Toast {
static void show(String message, {int duration}) {
OverlayEntry entry = OverlayEntry(builder: (context) {
return Container(
color: Colors.transparent,
margin: EdgeInsets.only(
top: MediaQuery.of(context).size.height * 0.7,
),
alignment: Alignment.center,
child: Center(
child: Container(
color: Colors.grey,
child: Padding(
padding: const EdgeInsets.all(8),
child: Material(
child: Text(
message,
style: TextStyle(),
),
),
),
),
),
);
});
Overlay.of(Global.context).insert(entry);
Future.delayed(Duration(seconds: duration ?? 2)).then((value) {
// 移除层可以通过调用OverlayEntry的remove方法。
entry.remove();
});
}
}
Loading同上,自己动手试一下比什么都来得快。