Flutter Overlay 你用上了么

这篇具有很好参考价值的文章主要介绍了Flutter Overlay 你用上了么。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Flutter Overlay 你用上了么

Flutter Overlay 你用上了么

前言

Flutter中的Overlay是一个用于在屏幕上显示浮层的组件。它可以用来在应用程序中创建弹出窗口、提示框、菜单、对话框等等。

Overlay通常用于在用户与应用程序交互时显示临时性的UI元素,例如:用户点击按钮时显示下拉菜单、用户长按屏幕时显示上下文菜单、显示警告或错误消息等等。

Overlay通常包含一个Stack布局,每个浮层都是一个Positioned widget,可以添加到Stack中。这样,可以将多个浮层叠加在一起,并控制它们的层次关系。

Flutter中的Overlay可以让开发者轻松创建复杂的UI,同时还可以保持应用程序的性能和响应度。

本文中提供的代码示例演示了如何在Flutter中使用Overlay制作工作覆盖层。Overlay包括两个基本组件:OverlayState和OverlayEntry。OverlayState管理所有OverlayEntry,OverlayEntry定义覆盖层中的内容。在示例中,OverlayEntry包含一个带有文本和颜色的容器,可以在屏幕上显示。这些条目可以通过OverlayState的insert和remove方法添加和删除。

原文 https://ducafecat.com/blog/flutter-overlay-did-you-use-it

Flutter Overlay 你用上了么

视频

https://www.bilibili.com/video/BV1qX4y1C7rb/

代码

https://github.com/ducafecat/flutter_develop_tips/tree/main/flutter_application_overlay

参考

https://api.flutter.dev/flutter/widgets/Overlay-class.html

https://api.flutter.dev/flutter/widgets/OverlayEntry-class.html

OverlayEntry

Overlay 通过将独立的子窗口小部件插入到重叠的堆栈中,使它们在其他窗口小部件之上“浮动”可视元素。覆盖允许每个小部件使用 OverlayEntry 对象管理它们在覆盖中的参与。

构造函数

OverlayEntry({
  required this.builder,
  bool opaque = false,
  bool maintainState = false,
})
  • builder:此属性用于此条目,并将在条目位置的覆盖中包含此构建器构建的小部件。
  • opaque:此属性用于获取bool值,该值决定此条目是否阻止整个覆盖。如果条目声明为不透明,则为了提高效率,除非它们具有maintainState设置,否则覆盖将跳过在该条目下面构建条目。
  • maintainState:如果您需要在 OverlayEntry中使用有状态的小部件,那么您需要将 maintainState设置为true,以便小部件可以保持其状态并接收生命周期方法。如果您只是在 OverlayEntry中显示一个静态小部件,则可以将 maintainState设置为false,以便小部件可以释放内存和资源,不会对性能产生过多影响。

OverlayEntry方法

只有一个OverlayEntry的方法

  • remove:此方法用于从覆盖层中删除此条目

OverlayState

Overlay的当前状态用于将OverlayEntries插入覆盖层中。

OverlayState方法

  • debugIsVisible:此方法用于检查给定的OverlayEntry是否可见,并返回布尔值。
  • insert:此方法用于将给定的OverlayEntry插入覆盖层中。
  • insertAll:此方法用于获取OverlayEntries的List,并将所有条目插入覆盖层中。您还可以指定上述和下述属性以说明要插入条目的顺序。
  • rearrange:它可以重新排列当前在屏幕上叠加的所有小部件。具体来说, rearrange方法会将最后添加的 OverlayEntry小部件移动到最上面,并将其他小部件移动到下面。这可以用于确保最新的 OverlayEntry始终位于最上面,并且可以接收用户的触摸事件等。

步骤

第一步:成员变量

  /// overlay 状态
  OverlayState? overlayState;

  /// overlay 层集合
  List<OverlayEntry> entriesList = [];
  @override
  void initState() {
    super.initState();
    // 获取 overlay 状态
    overlayState = Overlay.of(context);
  }
  @override
  void dispose() {
    // 销毁
    overlayState?.dispose();
    super.dispose();
  }

第二步:随机层显示

  // 随机位置显示层
  void showRandomOverlay(BuildContext context) {
    // 随机颜色
    final bgColor = Color.fromARGB(
      255,
      1 + Random().nextInt(254),
      1 + Random().nextInt(254),
      1 + Random().nextInt(254),
    );

    // 屏幕宽度
    final screenWidth = MediaQuery.of(context).size.width;

    // 随机屏幕高度
    final randomHeight =
        MediaQuery.of(context).size.height * Random().nextDouble();

    OverlayEntry? overlayEntry;
    overlayEntry = OverlayEntry(builder: (context) {
      return Positioned(
        // 指定位置
        left: 0,
        top: randomHeight,
        child: GestureDetector(
          // 点击删除
          onTap: () {
            overlayEntry?.remove();
            entriesList.remove(overlayEntry);
          },
          // 背景随机色
          child: Container(
            width: screenWidth,
            height: 100,
            color: bgColor,
            child: Center(
              // 提示文字
              child: Text(
                "这是一个 overlay ${Random().nextInt(100)} 层, 点击关闭",
                style: const TextStyle(
                  color: Colors.white,
                  fontSize: 20,
                  decoration: TextDecoration.none,
                ),
              ),
            ),
          ),
        ),
      );
    });
    overlayState?.insert(overlayEntry);
    entriesList.add(overlayEntry);
  }

第三步:控制按钮

  // 控制按钮
  Widget _buildBtns() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: [
        // 随机新增
        ElevatedButton(
          onPressed: () => showRandomOverlay(context),
          child: const Text("随机新增"),
        ),

        // 关闭所有
        ElevatedButton(
          onPressed: () {
            for (final entry in entriesList) {
              entry.remove();
            }
            entriesList = [];
          },
          child: const Text("关闭所有"),
        ),

        // 随机排序
        ElevatedButton(
          onPressed: () {
            // 从屏幕上移除
            for (final entry in entriesList) {
              entry.remove();
            }

            // 使用Random类创建随机数生成器
            Random random = Random();

            // 使用List的sublist()方法创建一个新列表
            List<OverlayEntry> shuffledEntries = entriesList.sublist(0);

            // 调用List的shuffle()方法,传入一个随机数生成器
            shuffledEntries.shuffle(random);

            // 插入界面
            overlayState?.insertAll(shuffledEntries);
          },
          child: const Text("随机排序"),
        ),
      ],
    );
  }

最后:主视图显示

  // 主视图
  Widget _mainView() {
    return Padding(
      padding: const EdgeInsets.only(top: 100),
      child: Align(
        alignment: Alignment.topCenter,
        child: _buildBtns(),
      ),
    );
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _mainView(),
    );
  }

完整代码

lib/overlay_view.dart

import 'dart:math';

import 'package:flutter/material.dart';

class OverlayUsePage extends StatefulWidget {
  const OverlayUsePage({super.key});

  @override
  State<OverlayUsePage> createState() => _OverlayUsePageState();
}

class _OverlayUsePageState extends State<OverlayUsePage{
  /// overlay 状态
  OverlayState? overlayState;

  /// overlay 层集合
  List<OverlayEntry> entriesList = [];

  // 随机位置显示层
  void showRandomOverlay(BuildContext context) {
    // 随机颜色
    final bgColor = Color.fromARGB(
      255,
      1 + Random().nextInt(254),
      1 + Random().nextInt(254),
      1 + Random().nextInt(254),
    );

    // 屏幕宽度
    final screenWidth = MediaQuery.of(context).size.width;

    // 随机屏幕高度
    final randomHeight =
        MediaQuery.of(context).size.height * Random().nextDouble();

    OverlayEntry? overlayEntry;
    overlayEntry = OverlayEntry(builder: (context) {
      return Positioned(
        // 指定位置
        left: 0,
        top: randomHeight,
        child: GestureDetector(
          // 点击删除
          onTap: () {
            overlayEntry?.remove();
            entriesList.remove(overlayEntry);
          },
          // 背景随机色
          child: Container(
            width: screenWidth,
            height: 100,
            color: bgColor,
            child: Center(
              // 提示文字
              child: Text(
                "这是一个 overlay ${Random().nextInt(100)} 层, 点击关闭",
                style: const TextStyle(
                  color: Colors.white,
                  fontSize: 20,
                  decoration: TextDecoration.none,
                ),
              ),
            ),
          ),
        ),
      );
    });
    overlayState?.insert(overlayEntry);
    entriesList.add(overlayEntry);
  }

  // 控制按钮
  Widget _buildBtns() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: [
        // 随机新增
        ElevatedButton(
          onPressed: () => showRandomOverlay(context),
          child: const Text("随机新增"),
        ),

        // 关闭所有
        ElevatedButton(
          onPressed: () {
            for (final entry in entriesList) {
              entry.remove();
            }
            entriesList = [];
          },
          child: const Text("关闭所有"),
        ),

        // 随机排序
        ElevatedButton(
          onPressed: () {
            // 从屏幕上移除
            for (final entry in entriesList) {
              entry.remove();
            }

            // 使用Random类创建随机数生成器
            Random random = Random();

            // 使用List的sublist()方法创建一个新列表
            List<OverlayEntry> shuffledEntries = entriesList.sublist(0);

            // 调用List的shuffle()方法,传入一个随机数生成器
            shuffledEntries.shuffle(random);

            // 插入界面
            overlayState?.insertAll(shuffledEntries);
          },
          child: const Text("随机排序"),
        ),
      ],
    );
  }

  // 主视图
  Widget _mainView() {
    return Padding(
      padding: const EdgeInsets.only(top: 100),
      child: Align(
        alignment: Alignment.topCenter,
        child: _buildBtns(),
      ),
    );
  }

  @override
  void initState() {
    super.initState();
    // 获取 overlay 状态
    overlayState = Overlay.of(context);
  }

  @override
  void dispose() {
    // 销毁
    overlayState?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _mainView(),
    );
  }
}

小结

本文提供了一个很好的介绍Flutter Overlay的概念和使用方法。无论是初学者还是有经验的开发人员,都可以从本文中获得新的知识和见解。如果你想在你的Flutter项目中实现工作覆盖层,本文是一个很好的起点。


© 猫哥 ducafecat.com

end

本文由 mdnice 多平台发布文章来源地址https://www.toymoban.com/news/detail-466848.html

到了这里,关于Flutter Overlay 你用上了么的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ssh连接没问题,今天竟然连不上了

    之前虚拟机ssh连接没问题,今天竟然连不上了。 打开虚拟机 ip a 网卡ens33没有ip root@ubuntu:/home/ww# ip addr 1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/

    2024年02月08日
    浏览(53)
  • 快来试试!免费用上GPT-4 !!!

    GPT-4是OpenAI上个月推出的最新人工智能语言模型, 它可以根据给定的文本或生成各种类似于人类语言甚至超越人类语言的文本 ,例如文章、故事、诗歌、代码、对话等。 GPT-4拥有1750亿个参数,是目前最大的语言模型之一,也是最强大的语言模型之一。 它不仅可以处理

    2024年02月06日
    浏览(45)
  • 让 Visual Studio 用上 ChatGPT

    Visual chatGPT Studio 是 Visual Studio 的一个免费扩展,它直接在 IDE 中添加了 chatGPT 功能。它允许用户以可以根据菜单功能的方式使用 chatGPT 。 该扩展提供了一组使用 ChatGPT 命令,可以在编辑器中选择你需要处理的代码或文本,然后右键就可以看到 Visual chatGPT Studio 和它的命令了。

    2024年02月07日
    浏览(44)
  • 让Visual Studio用上chatgpt

        最近小编思维发散“Visual Studio可以集成chatgpt吗?”,这样不就可以让chatgpt帮你写代码了吗?寻觅了一圈,还真有这个东西,那就是一个Visual Studio的扩展插件:Visual chatGPT Studio,虽然不是官方的,部分功能也可以值得一用。本文将介绍Visual chatGPT Studio及它的使用案例。

    2024年02月02日
    浏览(36)
  • 【深度学习】大模型卷到机器人上了

    当一项变革性技术出现后,以此为基础的技术就会像雨后春笋般蔓延。 就像Transformer出现后,以此为基础的大语言模型ChatGPT,视觉基础模型Segment Anything相继横空出世,并展现出强大的涌现能力。生成式AI可谓百花齐鸣,争相绽放。 继纯语言,纯视觉大模型后,多模态大模型

    2024年02月07日
    浏览(39)
  • 多年以后,PageHelper 又深深给我上了一课!

    多年不用PageHelper了,最近新入职的公司,采用了此工具集成的框架,作为一个独立紧急项目开发的基础。项目开发起来,还是手到擒来的,但是没想到,最终测试的时候,深深的给我上了一课。 我的项目发生了哪些奇葩现象? 一切的问题都要从我接受的项目开始说起, 在开发

    2024年02月20日
    浏览(35)
  • 为什么网络连接断开几十秒又连上了

    为什么网络连接断开几十秒又连上了!这种情况也是我们常碰到的!我们来看一下造成这种现象的原因是什么? 1.系统有病毒或者恶意软件或者插件! 处理方法:对电脑进行杀毒和清除恶意插件或者是软件! 2.如何你使用ADSL上网出现了这种情况: 之前小编也有发布过很多类

    2024年02月05日
    浏览(48)
  • 最新饿了么电脑脚本+获取cookie教程+代挂

     先上图片最新9/11可用,代挂 目录 cookie获取方式: 1.手机小蓝鸟抓包  2.手机/pc端网页获取cookie  电脑端方法一  电脑端方法二 手机端网页方法 所需资源下载: 免费代挂 写在前面:本人手机已root+使用小蓝鸟证书模块 不确保其他手机是否能正常使用 小蓝鸟选中目标软件后打开

    2023年04月09日
    浏览(61)
  • 饿了么输入框限制只能输入数字,并且保留小数

    可以使用饿了么ui中的input-number组件实现输入框只能输入数字,这样就不能输入数字以外的,controls隐藏输入框左右俩边的加减按钮,precision小数点保留多少位,2则是俩位,但是会导致默认值为0.00的情况,俩种解决办法, 第一:v-model中的字段默认要删除,因为vue的响应式特

    2024年02月13日
    浏览(92)
  • AI将会为人类插上了强力的翅膀

    半年过去了,以ChatGPT为首的大模型对这个世界产生了翻天覆地的变化,兴奋者有之,恐惧者有之,思索着亦有之。或许真如很多人的预测,AGI将会出现,人类作为硅基智慧的垫脚石遁入历史的红尘中。 不过目前短期十几年来看,人工智能替代人类估计还是科幻的事情,但是

    2024年02月11日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包