Flutter悬浮UI的设计Overlay组件

文章目录

  • APP开发经常要遇到的开发场景
  • Overlay 的介绍
  • Overlay的使用规则
  • 举例说明
    • 源码
    • 例子报错
      • 报错No Overlay widget found
      • 报错原因
      • 解决方法
    • 修改后的源码
  • 例子效果

APP开发经常要遇到的开发场景

有时候我们在开发APP的时候会遇到下面这些需求:

  • 在现有页面上添加浮动的悬浮按钮、气泡或菜单。
  • 实现全局的通知或提示弹窗。
  • 创建自定义的导航栏、底部导航或标签栏。
  • 构建模态对话框或底部弹出菜单。
  • 在屏幕上展示悬浮窗,比如 Flutter 版本的 Toast,任意位置的 PopWindow 等等。
  • 自定义Toast。
  • 在页面顶部悬浮某个widget。
    等等。
    这些场景都有一个共同特点,需要在当前UI上悬浮显示特定的UI。要用flutter来实现这些效果就要引出今天要学习的Overlay组件。

Overlay 的介绍

当需要在 Flutter 应用中在现有 UI 层上添加新的视图或交互时,可以使用 Overlay 组件。Overlay 允许将一个或多个小部件(称为 OverlayEntry)叠加在应用的现有 UI 上。
Overlay包括两个基本组件:OverlayState和OverlayEntry。OverlayState管理所有OverlayEntry,OverlayEntry定义覆盖层的内容。

Overlay的使用规则

  • 创建一个 Overlay 对象,通常使用 Overlay.of(context) 方法获取当前上下文中的 Overlay 对象。
  • 创建一个或多个 OverlayEntry 对象,这些对象将成为 Overlay 的子项。
  • 将 OverlayEntry 添加到 Overlay 中,通常使用 OverlayEntry 的 insert 或 add 方法。
  • 当需要显示或隐藏叠加层时,调用 OverlayEntry 的 markNeedsBuild 方法,并在 build 方法中定义要显示的小部件。
    可选:通过调整 OverlayEntry 的位置、大小和布局参数来控制叠加层的位置和样式。

举例说明

下面通过一个简单的例子来说明:例子要实现点击一个按钮会打开Overlay显示一个FloatingActionButton。

源码

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Overlay Example'),
        ),
        body: Center(
          child: ElevatedButton(
            child: Text('Open Overlay'),
            onPressed: () {
              showFloatingButtonOverlay(context);
            },
          ),
        ),
      ),
    );
  }
}

void showFloatingButtonOverlay(BuildContext context) {
  OverlayState? overlayState = Overlay.of(context);
  late OverlayEntry overlayEntry;

  // 创建 OverlayEntry
  overlayEntry = OverlayEntry(
    builder: (BuildContext context) {
      return Positioned(
        top: 100,
        right: 16,
        child: FloatingActionButton(
          onPressed: () {
            // 悬浮按钮被点击
            print('Floating Button Clicked');
            overlayEntry.remove(); // 移除 OverlayEntry
          },
          child: Icon(Icons.add),
        ),
      );
    },
  );

  // 将 OverlayEntry 添加到 Overlay 中
  overlayState?.insert(overlayEntry);
}

运行结果如图:

例子报错

本来想直接贴正确的代码的,但是觉得这个错误对初学者来说很容易犯,故单独列出来。

报错No Overlay widget found

点击Open Overlay按钮报错No Overlay widget found。如下图
Flutter悬浮UI的设计Overlay组件_第1张图片

报错原因

该错误提示是因为在使用 Overlay.of(context) 方法时,找不到可用的 Overlay 对象。

解决方法

确保按钮所在的 BuildContext 对象正确。在上述示例中,按钮的 onPressed 回调中使用的 BuildContext 应该是 Scaffold 的上下文,确保按钮在正确的上下文中定义和使用。

确保 Overlay 被正确地放置在应用的组件树中。在上述示例中,Overlay 组件应该在 MaterialApp 或 WidgetsApp 的下方,以确保它们在正确的层次结构中。

修改后的源码

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: OverlayExample(), // 使用 OverlayExample 作为主页
    );
  }
}

class OverlayExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Overlay Example'),
      ),
      body: Center(
        child: ElevatedButton(
          child: Text('Open Overlay'),
          onPressed: () {
            showFloatingButtonOverlay(context);
          },
        ),
      ),
    );
  }
}

void showFloatingButtonOverlay(BuildContext context) {
  OverlayState? overlayState = Overlay.of(context);
  late OverlayEntry overlayEntry;

  // 创建 OverlayEntry
  overlayEntry = OverlayEntry(
    builder: (BuildContext context) {
      return Positioned(
        top: 100,
        right: 16,
        child: FloatingActionButton(
          onPressed: () {
            // 悬浮按钮被点击
            print('Floating Button Clicked');
            overlayEntry.remove(); // 移除 OverlayEntry
          },
          child: Icon(Icons.add),
        ),
      );
    },
  );

  // 将 OverlayEntry 添加到 Overlay 中
  overlayState?.insert(overlayEntry);
}

例子效果

运行起来的效果如图:
Flutter悬浮UI的设计Overlay组件_第2张图片
点击Open Overlay按钮后的效果图如下:
Flutter悬浮UI的设计Overlay组件_第3张图片

你可能感兴趣的:(Flutter,flutter,悬浮,UI,Overlay,叠加UI)