[Flutter]Toast最正确的打开方式(没有之一)

现有的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同上,自己动手试一下比什么都来得快。

    原文作者:Brant白叔
    原文地址: https://www.jianshu.com/p/7534270bf737
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞