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的维护(增删排序等)功能,基本无须过多了解。

相关推荐

  1. flutterOverlay详解

    2023-12-06 14:44:06       39 阅读
  2. 深入了解FlutterOverlay介绍以及使用

    2023-12-06 14:44:06       15 阅读
  3. Flutter @protected 详解与使用

    2023-12-06 14:44:06       14 阅读
  4. Flutter】webview_flutter使用详解

    2023-12-06 14:44:06       18 阅读
  5. CSS全局值 initial inherit revert overlay unset

    2023-12-06 14:44:06       25 阅读
  6. invokeMethod 在 Flutter使用场景与详解

    2023-12-06 14:44:06       16 阅读
  7. Flutter详解及案例代码

    2023-12-06 14:44:06       37 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-06 14:44:06       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-06 14:44:06       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-06 14:44:06       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-06 14:44:06       20 阅读

热门阅读

  1. IDC网络设备监控脚本-FLOW流监控

    2023-12-06 14:44:06       28 阅读
  2. 代码随想录二刷 |队列与栈 |有效的括号

    2023-12-06 14:44:06       44 阅读
  3. ubuntu重启后下无wifi,蓝牙和飞行模式切换问题

    2023-12-06 14:44:06       40 阅读
  4. github可访问但无法clone问题

    2023-12-06 14:44:06       35 阅读
  5. Linux计算机系统参数获取和压力测试

    2023-12-06 14:44:06       38 阅读
  6. Ubuntu22.04LTS配置rsync服务

    2023-12-06 14:44:06       44 阅读
  7. [cmake] --- find_package

    2023-12-06 14:44:06       28 阅读
  8. 如何关闭vue项目中的[eslint]校验

    2023-12-06 14:44:06       40 阅读
  9. CSS外边距重叠:原理、结果

    2023-12-06 14:44:06       29 阅读
  10. LeetCode1005. Maximize Sum Of Array After K Negations

    2023-12-06 14:44:06       23 阅读