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

随着版权意识的加强,越来越多的应用开始在应用内部增加各种各样的水印信息,防止核心信息泄露,便于朔源。

效果如下:

在Flutter中增加全局水印的方式,目前有两种实现。

方案一,在native层添加一个遮罩层,但这种方式需要双端都要开发,效率低下,维护成本高,优点当然也有,那就是性能高。

方案二:直接在Flutter中添加一个悬浮层实现企微,飞书等界面的水印效果,就如上图中的效果一样。

为了凸显Flutter的高效,当然是直接使用Flutter中的Api进行实现。

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

dart 复制代码
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);

  @override
  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的特性,动态添加与删除。

dart 复制代码
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,毕竟不是所有界面都需要添加水印。

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

dart 复制代码
class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
  GlobalWaterMarkUtil waterMarkUtil = GlobalWaterMarkUtil();

  @override
  void initState() {
    super.initState();
    addGlobalWatermark();
  }

  ///添加全局水印
  void addGlobalWatermark(){
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      waterMarkUtil.addCustomWatermark(
          context,
          WaterMarkWidget(
            text: 'Hello Flutter \n ${DateTime.now()}',
          ));
    });
  }

  @override
  void dispose() {
    waterMarkUtil.removeWatermark();
    super.dispose();
  }
 }

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

相关推荐
技术男1 天前
flutter中怎么局部刷新
flutter
恋猫de小郭1 天前
Flutter 也有类 React Flow 的节点流程编辑器,快来了解下刚刚开源的 vyuh_node_flow
android·前端·flutter
火柴就是我1 天前
android:enableJetifier=true 再学习
android·flutter
星释1 天前
鸿蒙Flutter三方库适配指南-04.使用MacOS搭建开发环境
flutter·macos·harmonyos
消失的旧时光-19432 天前
Flutter 异步编程:Future 与 Stream 深度解析
android·前端·flutter
星释2 天前
鸿蒙Flutter三方库适配指南-02.Flutter相关知识基础
flutter·华为·harmonyos
傅里叶2 天前
Flutter项目使用 buf.build
flutter
恋猫de小郭2 天前
iOS 26 开始强制 UIScene ,你的 Flutter 插件准备好迁移支持了吗?
android·前端·flutter
yuanlaile2 天前
Flutter开发HarmonyOS鸿蒙App商业项目实战已出炉
flutter·华为·harmonyos
CodeCaptain2 天前
可直接落地的「Flutter 桥接鸿蒙 WebSocket」端到端实施方案
websocket·flutter·harmonyos