flutter添加水印、添加自定义水印、禁止截屏(Android)

一、前言

现实生活中,我们想要对应用的开发程序内容进行管控,避免暴露出敏感信息。因此,在很多的pc端的开发页面上,经常能看见水印,这种水印的实现,在html、vue等技术上对于开发过的人来说十分的简单。当然,App端同样也有很多的敏感信息,避免暴露出去因此需要加上水印。
自己这次的开发需求上就遇见了,因为是第一次接触flutter,对与很多东西都不懂更别说全局设置什么水印了,所以,在网上查询了好久,诸如“flutter 添加水印”、“fluter设置水印”…查询出来的博客、页面,屁都不是,满屏幕的什么涂鸦的方法乱七八糟,所以自己从pub.dev上面找出来的demo,仔细调试了调试,贴出源码,为各位提供参考,实现效果如下:
在这里插入图片描述

实现代码如下:

import 'dart:math';

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:disable_screenshots/disable_screenshots.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: RootApp());
  }
}

class RootApp extends StatefulWidget {
  @override
  _RootAppState createState() => _RootAppState();
}

class _RootAppState extends State<RootApp> {
  // 初始化插件
  DisableScreenshots _plugin = DisableScreenshots();

// 监控截屏行为的stream
  StreamSubscription<void> _screenshotsSubscription;
  int _screenshotsCount = 0;
  bool _disableScreenshots = false;

  @override
  void initState() {
    super.initState();
    _screenshotsSubscription = _plugin.onScreenShots.listen((event) {
      setState(() {
        _screenshotsCount++;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('冷月寒雪'),
      ),
      body: Column(
        children: <Widget>[
          Center(
            child: Text("监控到截屏次数:$_screenshotsCount"),
          ),
          Center(
            child: Text(_disableScreenshots ? "禁止截屏状态" : "允许截屏状态"),
          ),
          RaisedButton(
              onPressed: () {
                // 添加默认样式的水印
                _plugin.addWatermark(context, "默认水印",
                    rowCount: 4, columnCount: 8);
              },
              child: Text("添加默认水印")),
          RaisedButton(
              onPressed: () {
                // 添加自定义widget当做水印
                _plugin.addCustomWatermark(context,
                    Watarmark(rowCount: 3, columnCount: 10, text: "冷月韩雪"));
              },
              child: Text("添加自定义水印")),
          RaisedButton(
              onPressed: () {
              // 移除水印
                _plugin.removeWatermark();
              },
              child: Text("删除水印")),
          RaisedButton(
              onPressed: () async {
                bool flag = !_disableScreenshots;
                // 禁用或允许截屏(只支持iOS)
                await _plugin.disableScreenshots(flag);
                setState(() {
                  _disableScreenshots = flag;
                });
              },
              child: Text(_disableScreenshots
                  ? "允许截屏(仅android适用)"
                  : "禁用截屏(仅android适用)")),
          RaisedButton(
              onPressed: () {
                Navigator.of(context).push(MaterialPageRoute(
                    builder: (_) => Scaffold(
                          appBar: AppBar(
                            title: Text("我是新页面"),
                          ),
                          body: Center(child: Text("new page")),
                        )));
              },
              child: Text("进入新页面"))
        ],
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
//取消截屏监控可以调用cancel()方法
    if (_screenshotsSubscription != null) {
      _screenshotsSubscription.cancel();
    }
  }
}

class Watarmark extends StatelessWidget {
  final int rowCount;
  final int columnCount;
  final String text;

  const Watarmark(
      {Key key,
      @required this.rowCount,
      @required this.columnCount,
      @required this.text})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return IgnorePointer(
      child: Container(
          child: Column(
        children: creatColumnWidgets(),
      )),
    );
  }

  List<Widget> creatRowWdiges() {
    List<Widget> list = [];
    for (var i = 0; i < rowCount; i++) {
      final widget = Expanded(
          child: Center(
              child: Transform.rotate(
        angle: pi / 10,
        child: Text(
          text,
          style: TextStyle(
              color: Color(0x08000000),
              fontSize: 18,
              decoration: TextDecoration.none),
        ),
      )));
      list.add(widget);
    }
    return list;
  }

  List<Widget> creatColumnWidgets() {
    List<Widget> list = [];
    for (var i = 0; i < columnCount; i++) {
      final widget = Expanded(
          child: Row(
        children: creatRowWdiges(),
      ));
      list.add(widget);
    }
    return list;
  }
}

需要依赖如下:
在这里插入图片描述

  disable_screenshots: ^0.1.0

因为考虑到每个人版本不同的问题,这个依赖有的人会下载sdk报错,所以我把该源码也放在了下面,若果依赖下不出来,就调用源码实现,在上图main方法的 import 'package:disable_screenshots/disable_screenshots.dart 替换成倒入下面的dart文件,这样就可以完成水印的添加了。

import 'dart:io';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class DisableScreenshots {
  static DisableScreenshots _instance;
  factory DisableScreenshots() {
    if (_instance == null) {
      final MethodChannel methodChannel = const MethodChannel(
          "com.devlxx.DisableScreenshots/disableScreenshots");
      final EventChannel eventChannel =
          const EventChannel('com.devlxx.DisableScreenshots/observer');
      _instance = DisableScreenshots.private(methodChannel, eventChannel);
    }
    return _instance;
  }

  DisableScreenshots.private(this._methodChannel, this._eventChannel);
  final MethodChannel _methodChannel;
  final EventChannel _eventChannel;
  Stream<void> _onScreenShots;

  OverlayEntry _overlayEntry;

  void addWatermark(BuildContext context, String watermark,
      {int rowCount = 3, int columnCount = 10, TextStyle textStyle}) async {
    if (_overlayEntry != null) {
      _overlayEntry.remove();
    }
    OverlayState overlayState = Overlay.of(context);
    _overlayEntry = OverlayEntry(
        builder: (context) => DisableScreenshotsWatarmark(
              rowCount: rowCount,
              columnCount: columnCount,
              text: watermark,
              textStyle: textStyle ??
                  const TextStyle(
                      color: Color(0x08000000),
                      fontSize: 18,
                      decoration: TextDecoration.none),
            ));
    overlayState.insert(_overlayEntry);
    // return await _methodChannel.invokeMethod<void>("addWatermark", ['我是水印']);
  }

  void addCustomWatermark(BuildContext context, Widget widget) {
    if (_overlayEntry != null) {
      _overlayEntry.remove();
    }
    OverlayState overlayState = Overlay.of(context);
    _overlayEntry = OverlayEntry(builder: (context) => widget);
    overlayState.insert(_overlayEntry);
  }

  void removeWatermark() async {
    if (_overlayEntry != null) {
      _overlayEntry.remove();
      _overlayEntry = null;
    }
  }

  Stream<void> get onScreenShots {
    if (_onScreenShots == null) {
      _onScreenShots = _eventChannel.receiveBroadcastStream();
    }
    return _onScreenShots;
  }

  /// 只支持安卓
  Future<void> disableScreenshots(bool disable) async {
    if (Platform.isAndroid) {
      return await _methodChannel
          .invokeMethod("disableScreenshots", {"disable": disable});
    } else {
      print('仅Android平台支持禁用屏幕截图');
    }
  }
}

class DisableScreenshotsWatarmark extends StatelessWidget {
  final int rowCount;
  final int columnCount;
  final String text;
  final TextStyle textStyle;

  const DisableScreenshotsWatarmark({
    Key key,
    @required this.rowCount,
    @required this.columnCount,
    @required this.text,
    @required this.textStyle,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return IgnorePointer(
      child: Container(
          child: Column(
        children: creatColumnWidgets(),
      )),
    );
  }

  List<Widget> creatRowWdiges() {
    List<Widget> list = [];
    for (var i = 0; i < rowCount; i++) {
      final widget = Expanded(
          child: Center(
              child: Transform.rotate(
                  angle: pi / 10, child: Text(text, style: textStyle))));
      list.add(widget);
    }
    return list;
  }

  List<Widget> creatColumnWidgets() {
    List<Widget> list = [];
    for (var i = 0; i < columnCount; i++) {
      final widget = Expanded(
          child: Row(
        children: creatRowWdiges(),
      ));
      list.add(widget);
    }
    return list;
  }
}

有自定义水印、默认水印的方法,同时还有安卓系统的禁止截屏功能,需要用的到的同学参考参考吧。如有疑问,欢迎留言。

猜你喜欢

转载自blog.csdn.net/goGoing_/article/details/106816904