Code前端首页关于Code前端联系我们

使用Flutter Overlay - 自定义加载,Toast

terry 2年前 (2023-09-22) 阅读数 102 #移动小程序

背景:项目Toast已经尝试过这个other_flushbar包,得到了相当多的喜欢,但是在使用的时候遇到了问题,因为这个Toast的实现是使用类似PageRouteBuilder的形式new 打开路由页面,但一些页面组件如 showDialog 和 shouBottomSheet 也使用此方法。这会导致一个问题。如果Toast和dialog一起使用,当Toast出现而dialog同时消失时,就会发生路由冲突,造成更大的麻烦。

解决方案:Google 发现实现 Toast 的更好方法是 Overlay

chatgpt 的响应

在 Flutter 中,Overlay 处理程序用于创建覆盖。允许您从应用程序界面添加或删除覆盖并控制其显示和位置。
Overlay 组件本质上是一个 Stack,它允许您在层次结构中放置多个叠加层,并根据需要更改它们的顺序和位置。每个叠加层由 OverlayEntry 表示,它定义了Overlay 中要显示的具体内容。
使用 OverlayOverlayEntry,您可以在应用程序中的任何位置创建自定义叠加层,并将它们放置在其他组件之上。这对于创建交互式或浮动界面元素(例如弹出窗口、浮动按钮和通知栏)非常有用。
要使用overlay,可以使用 overlay.of (context) 方法在当前上下文中获取overlay。然后,您可以使用 insertinsert

方法将 OverlayEntry 添加到 Overlay。 如何修改 覆盖 已从: 中删除。

flutter_easyloading

我搜索了pub,发现了一个flutter_easyloading目录。它得到了很多人的喜欢,并且还支持加载和烘烤。下层也使用了Overlay实现,但是将其引入到项目中时发现了问题:

  1. 因为这个库是一个全局单例,虽然它同时提供了load和toast,但是它的一些自定义配置只能使用对于单个实例。 ,这意味着无法为 load 和 toast https://github 单独配置颜色。 com/nslogx/flutter_easyloading/issues/188,该项目有很多未解决的问题。不知道开发商有没有放弃。
  2. 我发现有很多第三方flutter库提供了一些配置选项。开发人员自定义样式,但这些配置往往难以满足用户的需求。其实和加载、吐司一样,第三方库只需要提供基本的动画,用户可以传入自己想要显示的内容。这样的话就不需要那么多配置参数了,用户也可以实现自己的需求(Flutter官方widget也提供了很多配置参数,调试起来非常费力。我们再抱怨一下,为什么可以呢?是吗?它不仅仅实现了基本逻辑,更具体地说是通过用户传递的widget来控制显示)

使用Overlay命令实现Toast和Loading

呈现效果:

Flutter Overlay 使用 —— 自定义 Loading、Toast

具体代码思路:

  • 在MaterialApp中设置叠加存储
    runApp(GetMaterialApp(
      ...
      builder: (context, child) => Scaffold(
        // 将整个根页面都放进 overlay 里面,其他的像 toast 等组件后续会动态的插入这个 Overlay 的 Stack 里面
        body: Overlay(
          initialEntries: [OverlayEntry(builder: (context) => child)],
        )
      ),
    );
  • 以Toast为例:
    class Toast {
    // toast 展现时间
    static int duration = 2500;
    // overlay entry
    static OverlayEntry? _overlayEntry;
    // overlay 存在时间计时器
    static Timer? _timer;
    // 对外暴露 success 和 error 方法
    static void success(String? message) {
      _show('success', message ?? '', context: Get.context!);
    }
    
    static void error(String? message) {
      _show('error', message ?? '', context: Get.context!);
    }
    
    // toast 核心逻辑
    static void _show(
      String type,
      String message, {
      required BuildContext context,
    }) {
      // 每次调用前先把上次的销毁,防止频繁调用
      _timer?.cancel();
      _overlayEntry?.remove();
      // 创建 overlay entry
      _overlayEntry = OverlayEntry(
        // toast 需要展现的内容,具体动画实现见文末
        // CustomerToastBody 就是 toast 具体要展现的样式,完全交给使用者自己定义
        builder: (ctx) => CutomerAnimateWidget(child: CustomerToastBody()),
      );
      // 将该自定义的 overlay entry 插入到顶层 overlayentry stack 中
      Overlay.of(context).insert(_overlayEntry!);
    
      // 一定时间后自动关闭 overlay entry
      _timer = Timer(Duration(milliseconds: duration), () {
        _overlayEntry?.remove();
        _overlayEntry = null;
      });
    }
    }
  • 抛开动画不谈,上面的代码完全实现了一个2.5s自动消失的Toast
  • 完整的实现,包括动画,看下面的链接 Toast https://gist.github.com/hugeorange/ adb11487d8803cbd6aa3338cc399204c点击预览
  • 加载e3e53

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门