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永远在栈底,所以水印将一直悬浮在所有页面之上。

相关推荐
融云3 小时前
集成指南:如何采用融云 Flutter IMKit 实现双端丝滑社交体验
flutter
EndingCoder14 小时前
跨平台移动开发框架React Native和Flutter性能对比
flutter·react native·react.js
Double Point14 小时前
`RotationTransition` 是 Flutter 中的一个动画组件,用于实现旋转动画效果
flutter
亚洲小炫风14 小时前
flutter 项目工程文件夹组织结构
flutter·flutter工程结构
Double Point14 小时前
Flutter 中 vsync
flutter
Double Point19 小时前
ScaleTransition 是 Flutter 中的一个动画组件,用于实现缩放动画效果。
flutter
saxihuangxing20 小时前
flutter build apk出现的一些奇怪的编译错误
flutter
恋猫de小郭2 天前
Flutter 合并 ‘dot-shorthands‘ 语法糖,Dart 开始支持交叉编译
android·flutter·ios
林家凌宇2 天前
Flutter 3.29.3 花屏问题记录
android·flutter·skia
恋猫de小郭2 天前
React Native 前瞻式重大更新 Skia & WebGPU & ThreeJS,未来可期
android·javascript·flutter·react native·react.js·ios