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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/33644.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【记录】实践场景

Apache Doris 在京东搜索实时 OLAP 探索与实践 https://doris.apache.org/zh-CN/blog/JD_OLAP/ 通过对比开源的几款实时OLAP引擎,我们发现doris和clickhouse能够满足我们的需求,但是clickhouse的并发度太低是个潜在的风险,而且clickhouse的数…

css新特性(五)

css基础(一)css基础(一)_上半场结束,中场已休息,下半场ing的博客-CSDN博客Emmet语法Emmet语法_上半场结束,中场已休息,下半场ing的博客-CSDN博客css基础(二)c…

多元分类预测 | Matlab粒子群算法(PSO)优化混合核极限学习机(HKELM)分类预测,多特征输入模型,PSO-HKELM分类预测

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元分类预测 | Matlab粒子群算法(PSO)优化混合核极限学习机(HKELM)分类预测,多特征输入模型,PSO-HKELM分类预测 多特征输入单输出的二分类及多分类模型。程序内注释详细,直接替换数据就可以用。程序语言为matl…

面向切面编程-AOP

Aop 概述&#xff1a;Aspect Oriented Programming(面向切面编程、面向方面编程)&#xff0c;即面向特定的方法编程,对原有的方法进行附加、增强 动态代理是面向切面编程的主流实现 实现步骤 pom文件中导入AOP依赖 <dependency><groupId>org.springframework.…

Spring Boot中的事务隔离级别

Spring Boot中的事务隔离级别 介绍 Spring Boot是一个流行的Java框架&#xff0c;它提供了许多方便的注解和工具&#xff0c;使得数据库操作变得更加容易。其中&#xff0c;事务隔离级别是Spring Boot中一个非常重要的概念&#xff0c;它可以帮助开发者控制数据库操作的并发性…

Jmeter(jmeter-plugins插件的安装使用)

目录 一、安装JMter Plugins 二、Custom Thread Groups插件 Stepping Thread Group 元件 Ultimate Thread Group 一、安装JMter Plugins 1、官网下载 JMeter Plugins 的jar包 2. 将下载的jar包复制到 %JMETER_HOME%\lib\ext 目录下 3. 启动 JMeter --> Options -->…

Chrome/Edge 浏览器多账号登录,测试同一业务系统的不同账号角色

文章目录 如何使用多账户&#xff1f;ChromeEdge 虽然说用不同浏览器测试也比较方便、还能顺带测试多浏览器兼容问题…… 但我是开发呀&#xff0c;我只想用我最习惯的谷歌浏览器完成快速开发&#xff0c;把功能铺上&#xff0c;专注于业务逻辑的开发 这些浏览器差异等只会给我…

vue+elementui实现英雄联盟道具城

目录 一、效果图 1.首页 2.商品列表、分类 二、实现重点讲解 1.首页轮播图 1.1技术实现&#xff1a; 1.2.鼠标聚焦切换图片事件 2.首页tab切换 3.商品列表实现 三、项目结构说明 四、总结 一、效果图 1.首页 项目与官方效果没有太大差异&#xff1a; 游戏导航&#xff1…

【SQL应知应会】分析函数的点点滴滴(一)

欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 本文收录于SQL应知应会专栏,本专栏主要用于记录对于数据库的一些学习&#xff0c;有基础也有进阶&#xff0c;有MySQL也有Oracle 分析函数的点点滴滴 1.什么是分析函数&#xff1a;…

Ubuntu离线安装Telnet服务

通过ssh上传telnet包&#xff0c;下载地址&#xff1a;telnet-0.17-41.2build1-amd64资源-CSDN文库 解压telnet包&#xff1a; tar -xzvf telnet_0.17-41.2build1_amd64.tar.gz 安装telnet服务&#xff1a; dpkg -i telnet_0.17-41.2build1_amd64.deb 安装完毕&#xff0c;测…

win10笔记本电脑总是自动休眠解决办法

1、运行regedit&#xff0c;进入注册表编辑器&#xff1b; 2、在打开的注册表编辑器左侧定位到&#xff1a;计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\PowerSettings\238C9FA8-0AAD-41ED-83F4-97BE242C8F20\7bc4a2f9-d8fc-4469-b07b-33eb785aaca0&…

Keras-深度学习-神经网络-电影评论情感分析模型

目录 模型搭建 模型训练 模型搭建 使用到的数据集为IMDB电影评论情感分类数据集&#xff0c;该数据集包含 50,000 条电影评论&#xff0c;其中 25,000 条用于训练&#xff0c;25,000 条用于测试。每条评论被标记为正面或负面情感&#xff0c;因此该数据集是一个二分类问题。…

MySql高级篇-006 MySQL架构篇-02MySQL的数据目录:数据库下的主要目录结构、文件系统如何存储数据

第02章_MySQL的数据目录 1.MySQL8的主要目录结构 # 查询名称叫做mysql的文件目录都有哪些[rootatguigu07 ~]# find / -name mysql安装好MySQL 8之后&#xff0c;我们查看如下的目录结构&#xff1a; 1.1 数据库文件的存放路径 MySQL数据库文件的存放路径&#xff1a;/var/…

【Linux】4、BootLoader:UBoot | BIOS、BMC 介绍

文章目录 一、bootloader1.1 uboot 二、BIOS2.1 grub 三、BMC3.1 原理3.2 使用场景3.3 IPMI 规范3.4 配置和使用3.4.1 通过 ipmitool 设置 BMC IP3.4.2 通过 BIOS 设置 BMC IP 一、bootloader 参考 windows开机时会首先加载bios&#xff0c;然后是系统内核&#xff0c;最后启…

第九十三天学习记录:C++核心:类和对象Ⅱ(五星重要)

对象的初始化和清理 构造函数和析构函数 对象的初始化和清理也是两个非常重要的安全问题 一个对象或者变量没有初始化状态&#xff0c;对其使用后果是未知 同样的使用完一个对象或变量&#xff0c;没有及时清理&#xff0c;也会造成一定的安全问题 c利用了构造函数和析构函数…

React Native 集成到iOS原有的项目上

1.官方说明地址&#xff1a; 集成到现有原生应用 2. 主要步骤说明 把 React Native 组件集成到 iOS 应用中有如下几个主要步骤&#xff1a; 配置好 React Native 依赖和项目结构。了解你要集成的 React Native 组件。使用 CocoaPods&#xff0c;把这些组件以依赖的形式加入到项…

机器学习复习6

机器学习复习 1 - 在机器学习的背景下&#xff0c;什么是诊断(diagnostic)&#xff1f; A. 这指的是衡量一个学习算法在测试集(算法没有被训练过的数据)上表现如何的过程 B. 迅速尝试尽可能多的不同方法来改进算法&#xff0c;从而看看什么方法有效 C. 机器学习在医疗领域的应用…

Python 基本数据类型(五)

文章目录 每日一句正能量List&#xff08;列表&#xff09;结语 每日一句正能量 营造良好的工作和学习氛围&#xff0c;时刻牢记宗旨&#xff0c;坚定信念&#xff0c;胸怀全局&#xff0c;埋头苦干&#xff0c;对同事尊重信任谅解&#xff0c;发扬团体协作精神&#xff0c;积极…

让集合数据操控指尖舞动:迭代器和生成器的精妙之处

文章目录 &#x1f499;迭代器&#xff08;Iterator&#xff09;迭代器的特点&#xff1a;迭代器的优点&#xff1a;代码案例&#xff1a; &#x1f49a;生成器&#xff08;Generator&#xff09;生成器的特点&#xff1a;生成器的优点&#xff1a;代码案例&#xff1a; &#…

在WSL2中安装IntelliJ IDEA开发工具

一、wsl支持图形 windows安装xming https://sourceforge.net/projects/xming/ 添加白名单 查看服务器ip ifconfig 编辑配置文件(结合自己的安装目录) ‪D:\ProgramFiles\Xming\X0.hosts 启动Xlaunh wsl 配置并验证 #b编辑配置文件 vi ~/.bashrc #末尾增加配置 export DI…