Flutter悬浮UI的设计Overlay组件

请添加图片描述

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。如下图
image.png

报错原因

该错误提示是因为在使用 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);
}

例子效果

运行起来的效果如图:
image.png
点击Open Overlay按钮后的效果图如下:
image.png

总结

在Flutter中,Overlay(叠加层)是一种特殊的控件,它可以在页面的顶部显示另一个独立的层级。Overlay通常用于在页面上显示浮动的元素,例如悬浮按钮、对话框、通知等。下面是对Flutter中Overlay控件的总结:

  • Overlay Widget(叠加层控件):
    Flutter中的Overlay控件是一个Widget,它用于创建和管理叠加层。它本身不可见,但可以包含多个可见的OverlayEntry。

  • OverlayEntry(叠加层条目):
    OverlayEntry是Overlay中的条目,它代表了要在叠加层上显示的内容。每个OverlayEntry都可以包含一个Widget,并定义了在叠加层上的位置和大小。

  • OverlayState(叠加层状态):
    OverlayState是与Overlay关联的状态对象,它用于添加、移除和管理OverlayEntry。可以通过BuildContext的方法来获取OverlayState对象。

  • 添加和移除OverlayEntry:
    使用OverlayState对象的方法,可以将OverlayEntry添加到Overlay中,并通过调用remove方法将其从Overlay中移除。

  • OverlayEntry的位置和大小:
    OverlayEntry可以通过设置Positioned或Align等控件来确定其在叠加层上的位置和大小。可以使用top、bottom、left、right等属性来定位OverlayEntry。

在页面上显示悬浮按钮、提示框、通知等浮动元素。
创建全局的可见元素,例如全局加载指示器、底部导航栏等。
实现页面过渡动画效果,例如页面切换时的渐隐渐显效果。

Flutter中的Overlay控件是一种用于创建和管理叠加层的特殊控件。它通过OverlayState来添加和移除OverlayEntry,每个OverlayEntry可以包含一个Widget,并通过定位控件设置其位置和大小。Overlay常用于显示浮动的元素、创建全局可见元素和实现页面过渡动画效果。

  • 62
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 72
    评论
评论 72
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值