flutter的Overlay详解

Overlay

用于在屏幕上显示浮层的组件

定义及作用

  • 用于在屏幕上显示浮层的组件。
  • 创建弹出窗口、提示框、菜单、对话框等。

源码分析

复制代码
/// Overlay的设计思路
class Overlay extends StatefulWidget
//可以看出Overlay是一个有状态的widget,直接看对应的OverlayState里面的实现。
final List<OverlayEntry> _entries = <OverlayEntry>[];
//OverlayState里面维护OverlayEntry的列表,那么OverlayEntry是什么?

/// 在OverlayEntry注释里有这样一段:
Because an [Overlay] uses a [Stack] layout, overlay entries can use [Positioned] and [AnimatedPositioned] to position themselves within the overlay.
//这句话可以理解为Overlay包含一个Stack布局,每个浮层都是一个Positioned widget,可以添加到Stack中。
又因为Stack是可以覆盖的,所以就能做出浮窗等效果。

/// 至此已经明白了一个基本思路:OverlayEntry是浮窗的UI,而OverlayState通过维护OverlayEntry来显示对应的UI。那么怎么绘制的呢?
Widget build(BuildContext context) {
    ...
    for (int i = _entries.length - 1; i >= 0; i -= 1) {
        ...
        children.add(_OverlayEntryWidget(
          key: entry._key,
          entry: entry,
        ));
// 至此,在build里,通过_OverlayEntryWidget这个实际绘制UI的widget绘制,然后add给children,children在给真正绘制的UI的地方(这就不继续跟下去了,这里着重发现Overlay的设计思路)

/// 总结:OverlayEntry是浮窗的UI,而OverlayState在build遍历OverlayEntry的列表来绘制每一个OverlayEntry。

使用举例

  • 基于上面总结原理,使用Overlay就需要在OverlayEntry里绘制UI,然后add给OverlayState。

  • 如下(步骤在注释上):

    class _MyHomePageState extends State<MyHomePage> {
    @override
    Widget build(BuildContext context) {
    return SafeArea(
    child: Scaffold(
    body: Column(
    children: [
    ElevatedButton(
    onPressed: () => btn1(context),
    child: const Text("btn1"),
    ),
    ],
    ),
    ),
    );
    }

    复制代码
    void btn1(BuildContext context) {
      /// 步骤1:绘制OverlayEntry的UI
      OverlayEntry? overlayEntry;
      overlayEntry = OverlayEntry(builder: (context) {
        return Positioned(
          // 指定位置
          left: 0,
          top: 100,
          child: GestureDetector(
            // 点击删除
            onTap: () {
              overlayEntry?.remove();
            },
            // 背景随机色
            child: Container(
              width: 100,
              height: 100,
              color: Colors.red,
              child: const Center(
                // 提示文字
                child: Text(
                  "这是一个 overlay 浮层, 点击关闭",
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 10,
                    decoration: TextDecoration.none,
                  ),
                ),
              ),
            ),
          ),
        );
      });
      /// 步骤2:把OverlayEntry的添加给overlayState。overlayState自己就会去setState展示
      OverlayState? overlayState = Overlay.of(context);
      overlayState.insert(overlayEntry);
      /// 步骤2:实际使用时通过Overlay.of(context)获得OverlayState要在dispose()时销毁
    }

    }

补充

OverlayEntry

  • 构造函数及描述参数作用:

    OverlayEntry({
    required this.builder, // 绘制UI
    bool opaque = false, // 是否不透明的,设置为true,就会让当前屏幕除了UI,都被遮盖,因为不透明嘛
    bool maintainState = false, //绘制的UI里如果没有用StatefulWidget,就设置为false,如果用了并且希望接收到外层的setState就设置为true
    })

OverlayState

  • 前面说了OverlayState是维护OverlayEntry的。而实际开发中弹框也不会弹多个浮层令人厌烦,所以OverlayState的维护(增删排序等)功能,基本无须过多了解。
相关推荐
Lionel68911 分钟前
Flutter 鸿蒙:获取真实轮播图API数据
flutter
千逐681 小时前
《基于 Flutter for OpenHarmony 的沉浸式天气可视化系统设计与实现》
flutter
一只大侠的侠1 小时前
Flutter开源鸿蒙跨平台训练营 Day8获取轮播图网络数据并实现展示
flutter·开源·harmonyos
sugar_hang1 小时前
Flutter 中的 TCP
flutter
子春一3 小时前
Flutter for OpenHarmony:形状拼图:基于路径几何与空间吸附的交互式拼图系统架构解析
flutter·系统架构
ujainu12 小时前
Flutter + OpenHarmony 游戏开发进阶:用户输入响应——GestureDetector 实现点击发射
flutter·游戏·openharmony
hudawei99612 小时前
TweenAnimationBuilder和AnimatedBuilder两种动画的比较
flutter·ui·动画·tweenanimation·animatedbuilder
ujainu13 小时前
Flutter + OpenHarmony 实现无限跑酷游戏开发实战—— 对象池化、性能优化与流畅控制
flutter·游戏·性能优化·openharmony·endless runner
ZH154558913114 小时前
Flutter for OpenHarmony Python学习助手实战:自动化脚本开发的实现
python·学习·flutter
晚烛15 小时前
CANN + 物理信息神经网络(PINNs):求解偏微分方程的新范式
javascript·人工智能·flutter·html·零售