当前位置: 首页 > news >正文

Flutter中添加全局防护水印的实现

随着版权意识的加强,越来越多的应用开始在应用内部增加各种各样的水印信息,防止核心信息泄露,便于朔源。
效果如下:
在这里插入图片描述

在Flutter中增加全局水印的方式,目前有两种实现。
方案一,在native层添加一个遮罩层,但这种方式需要双端都要开发,效率低下,维护成本高,优点当然也有,那就是性能高。
方案二:直接在Flutter中添加一个悬浮层实现企微,飞书等界面的水印效果,就如上图中的效果一样。
为了凸显Flutter的高效,当然是直接使用Flutter中的Api进行实现。

第一步:创建所需的水印样式:

import 'dart:math';import 'package:flutter/material.dart';class WaterMarkWidget extends StatelessWidget {final int rowCount;//控制每一行显示的水印个数final int columnCount;//控制每一列显示的个数final String text;//水印文案const WaterMarkWidget({Key? key,this.rowCount = 2,this.columnCount = 3,required this.text,}) : super(key: key);Widget build(BuildContext context) {return IgnorePointer(//这个很关键,一定要忽略焦点事件child: SafeArea(child: Padding(padding: const EdgeInsets.only(top: 50),child: Column(children: createColumnWidgets(),),),),);}List<Widget> createRowWidgets() {List<Widget> list = [];for (var i = 0; i < rowCount; i++) {final widget = Expanded(child: Center(child: Transform.rotate(angle: -pi / 4.5,child: Opacity(opacity: 0.2,child: Text(text,style:  const TextStyle(fontSize: 12,color: Colors.blue,),),),),),);list.add(widget);}return list;}List<Widget> createColumnWidgets() {List<Widget> list = [];for (var i = 0; i < columnCount; i++) {final widget = Expanded(child: Row(children: createRowWidgets(),));list.add(widget);}return list;}
}

在这段代码中,核心要注意的是,增加焦点忽略,不然就会出现焦点抢占的问题。

第二步:创建一个水印管理工具类

主要使用了OverlayEntry的特性,动态添加与删除。

import 'package:flutter/material.dart';class GlobalWaterMarkUtil {static final GlobalWaterMarkUtil _singleton = GlobalWaterMarkUtil._internal();factory GlobalWaterMarkUtil() {return _singleton;}GlobalWaterMarkUtil._internal();OverlayEntry? _overlayEntry;/// 添加自定义水印。将[widget]覆盖在所有视图的最上层void addCustomWatermark(BuildContext context, Widget widget) {_overlayEntry?.remove();OverlayState? overlayState = Overlay.of(context);_overlayEntry = OverlayEntry(builder: (context) => widget);overlayState.insert(_overlayEntry!);}/// 移除水印Future<void> removeWatermark() async {if (_overlayEntry != null) {_overlayEntry?.remove();_overlayEntry = null;}}
}

工具类内容简单,主要用于添加和删除OverlayEntry,毕竟不是所有界面都需要添加水印。

第三步:在需要的界面增加水印

class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {GlobalWaterMarkUtil waterMarkUtil = GlobalWaterMarkUtil();void initState() {super.initState();addGlobalWatermark();}///添加全局水印void addGlobalWatermark(){WidgetsBinding.instance.addPostFrameCallback((timeStamp) {waterMarkUtil.addCustomWatermark(context,WaterMarkWidget(text: 'Hello Flutter \n ${DateTime.now()}',));});}void dispose() {waterMarkUtil.removeWatermark();super.dispose();}}

经过这简单的三步,即可实现全局水印的效果,在使用时,一定要记得在dispose中调用移除函数,不然容易出现水印重叠的效果,如果是针对整个App添加水印,那只需要在Flutter的HomePage里面添加一次即可,因为HomePage永远在栈底,所以水印将一直悬浮在所有页面之上。

相关文章:

Flutter中添加全局防护水印的实现

随着版权意识的加强&#xff0c;越来越多的应用开始在应用内部增加各种各样的水印信息&#xff0c;防止核心信息泄露&#xff0c;便于朔源。 效果如下&#xff1a; 在Flutter中增加全局水印的方式&#xff0c;目前有两种实现。 方案一&#xff0c;在native层添加一个遮罩层&a…...

BGP(Border Gateway Protocol)路由收集器

全球 BGP&#xff08;边界网关协议&#xff09;路由收集器的分布情况以及相关数据。以下是主要的信息解读&#xff1a; 地图标记&#xff1a; 每个绿色点代表一个路由收集器的位置。路由收集器分布在全球不同的地区&#xff0c;覆盖了五大区域&#xff1a; ARIN&#xff08;美…...

【DAGMM】直接跑tip

1.from sklearn.externals import joblib 版本高 joblib没有 直接pip install joblib&#xff0c;然后 import joblib 2.AttributeError: module ‘tensorflow’ has no attribute ‘set_random_seed’ # tf.set_random_seed(args.seed)#tf<2.0 tf.random.set_seed(args.s…...

vscode中调用deepseek实现AI辅助编程

来自 Python大数据分析 费弗里 1 简介 大家好我是费老师&#xff0c;最近国产大模型Deepseek v3新版本凭借其优秀的模型推理能力&#xff0c;讨论度非常之高&#x1f525;&#xff0c;且其官网提供的相关大模型API接口服务价格一直走的“价格屠夫”路线&#xff0c;性价比很高…...

AI大模型语音识别转文字

提取音频 本项目作用在于将常见的会议录音文件、各种语种音频文件进行转录成相应的文字&#xff0c;也可从特定视频中提取对应音频进行转录成文字保存在本地。最原始的从所给网址下载对应视频和音频进行处理。下载ffmpeg(https://www.gyan.dev/ffmpeg/builds/packages/ffmpeg-…...

可由 (5V) 单片机直接驱动的模块

可由 &#xff08;5V&#xff09; 单片机 直接驱动的模块 1. 传感器类 元器件描述温度传感器DS18B20&#xff08;数字温度传感器&#xff09;光强传感器光敏电阻&#xff08;通过 ADC 读取&#xff09;红外传感器红外接收模块&#xff08;如 VS1838&#xff09;超声波传感器HC…...

vue使用树形结构展示文件和文件夹

1. 树形结构显示 显示文件夹和文件&#xff1a;使用 el-tree 组件展示树形结构&#xff0c;文件夹和文件的图标通过 el-icon 进行动态显示。文件夹使用 Folder 图标&#xff0c;文件使用 Files 图标。节点点击&#xff1a;点击树形节点后&#xff0c;会将选中的节点保存到 sel…...

PHP框架+gatewayworker实现在线1对1聊天--聊天界面布局+创建websocket连接(5)

文章目录 聊天界面布局html代码 创建websocket连接为什么要绑定&#xff1f; 聊天界面布局 在View/Index目录下创建index.html html代码 <div id"chat"><div id"nbar"><div class"pull-left">与牛德胜正在聊天...</div…...

LinuxUbuntu打开VSCode白屏解决方案

解决方法是 以root权限打开VSCode sudo /usr/share/code/code --no-sandbox --unity-launch...

在 ESP 上运行 AWTK

AWTK 基于 esp 的移植。 测试硬件平台为 ESP32-S3-Touch-LCD-4.3&#xff0c;其它平台请根据实际平台自行调整。 安装下载工具 建议下载离线版本 ESP IDF v5.3.2 下载代码 git clone https://github.com/zlgopen/awtk-esp.git cd awtk-esp git clone https://github.com/zlg…...

硬件工程师面试题 21-30

把常见的硬件面试题进行总结&#xff0c;方便及时巩固复习。其中包括网络上的资源、大佬们的大厂面试题&#xff0c;其中可能会题目类似&#xff0c;加强印象即可。 更多硬件面试题&#xff1a;硬件工程师面试题 1-10硬件工程师面试题 11-20 21、单片机最小系统需要什么&#x…...

开源架构的容器化部署优化版

上三篇文章推荐&#xff1a; 开源架构的微服务架构实践优化版&#xff08;New&#xff09; 开源架构中的数据库选择优化版&#xff08;New&#xff09; 开源架构学习指南&#xff1a;文档与资源的智慧锦囊&#xff08;New&#xff09; 我管理的社区推荐&#xff1a;【青云交社区…...

Qt使用CMake编译项目时报错:#undefined reference to `vtable for MainView‘

博主将.h文件和.cpp文件放到了不同的文件目录下面&#xff0c;如下图所示&#xff1a; 于是构建项目的时候就报错了#undefined reference to vtable for MainView&#xff0c;这个是由于src/view目录下的CMake无法自动moc头文件导致的&#xff0c;需要手动moc include/view目录…...

python学习笔记—12—

1. 布尔类型 (1) 定义 (2) 比较运算符 (3) 代码演示 1. 手动定义 bool_1 True bool_2 False print(f"bool_1的内容是&#xff1a;{bool_1}, 类型是&#xff1a;{type(bool_1)}") print(f"bool_2的内容是&#xff1a;{bool_2}, 类型是&#xff1a;{type(bool…...

==和===的区别,被坑的一天

在 JavaScript 中&#xff0c; 和 都用于比较两个值&#xff0c;但它们有一个重要的区别&#xff1a; 1. (宽松相等运算符) 进行比较时&#xff0c;会 自动类型转换&#xff08;也叫做强制类型转换&#xff09;&#xff0c;即如果比较的两个值的类型不同&#xff0c;JavaScr…...

基于 GPUTasker 的 GPU 使用情况钉钉推送机器人实现

引言 https://github.com/cnstark/gputasker 随着 AI 模型的广泛应用&#xff0c;GPU 成为团队中最重要的资源之一。然而&#xff0c;如何实时监控 GPU 的使用情况并及时通知团队是一个值得关注的问题。为了更好地管理显卡资源&#xff0c;本文基于 GPUTasker&#xff0c;实现了…...

Python自学 - 函数初步(内置函数、模块函数、自定义函数)

1 Python自学 - 函数初步(内置函数、模块函数、自定义函数) 1.1 内置函数 几乎所有的编程都会提供一些内置函数&#xff0c;以便完成一些最基本的任务&#xff0c;Python提供了丰富的内置函数&#xff0c;熟悉内置函数可以给工作带来极大便利。   Python官方的内置函数介绍网…...

【生活】冬天如何选口罩(医用口罩,N95, KN95还是KP95?带不带呼吸阀门?带不带活性炭?)

&#x1f4a1;总结一下就是&#xff1a; 日常防护的话&#xff0c;医用口罩就可以啦。要是想长时间佩戴N95&#xff08;KN95&#xff09;口罩的话也可以. 在高风险环境&#xff08;像医院、疫情防控期间&#xff09;&#xff0c;一定要选不带呼吸阀门的N95口罩KN95&#xff09…...

HTML5新特性|01 音频视频

音频 1、Audio (音频) HTML5提供了播放音频文件的标准 2、control(控制器) control 属性供添加播放、暂停和音量控件 3、标签: <audio> 定义声音 <source> 规定多媒体资源,可以是多个<!DOCTYPE html> <html lang"en"> <head><…...

迅为RK3568开发板编译Android12源码包-设置屏幕配置

在源码编译之前首先要确定自己想要使用的屏幕并修改源码&#xff0c;在编译镜像&#xff0c;烧写镜像。如下图所示&#xff1a; 第一步&#xff1a;确定要使用的屏幕种类&#xff0c;屏幕种类选择如下所示&#xff1a; iTOP-3568 开发板支持以下种类屏幕&#xff1a; 迅为 LV…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

pycharm 设置环境出错

pycharm 设置环境出错 pycharm 新建项目&#xff0c;设置虚拟环境&#xff0c;出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...

Python训练营-Day26-函数专题1:函数定义与参数

题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一个名为 calculate_circle_area 的函数&#xff0c;该函数接收圆的半径 radius 作为参数&#xff0c;并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求&#xff1a;函数接收一个位置参数 radi…...

前端调试HTTP状态码

1xx&#xff08;信息类状态码&#xff09; 这类状态码表示临时响应&#xff0c;需要客户端继续处理请求。 100 Continue 服务器已收到请求的初始部分&#xff0c;客户端应继续发送剩余部分。 2xx&#xff08;成功类状态码&#xff09; 表示请求已成功被服务器接收、理解并处…...

大数据驱动企业决策智能化的路径与实践

&#x1f4dd;个人主页&#x1f339;&#xff1a;慌ZHANG-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 一、引言&#xff1a;数据驱动的企业竞争力重构 在这个瞬息万变的商业时代&#xff0c;“快者胜”的竞争逻辑愈发明显。企业如何在复杂环…...

【技巧】dify前端源代码修改第一弹-增加tab页

回到目录 【技巧】dify前端源代码修改第一弹-增加tab页 尝试修改dify的前端源代码&#xff0c;在知识库增加一个tab页"HELLO WORLD"&#xff0c;完成后的效果如下 [gif01] 1. 前端代码进入调试模式 参考 【部署】win10的wsl环境下启动dify的web前端服务 启动调试…...