Flutter笔记--加水印

Flutter开发中,常常需要给某些页面加水印,有的是加文字水印,有的是需要加logo水印,简单总结如下:

API:

Stack:层叠布局,让水印 "盖在" 页面内容上面

IgnorePointer:水印不拦截点击事件

Opacity:让水印半透明,不遮挡内容

Transform.rotate:让水印斜着显示

CustomPaint:底层画布绘制,防截图、铺满屏幕水印

栗子:

Dart 复制代码
import 'package:flutter/material.dart';

void main() {
  runApp(const MyWaterMark01());
}

class MyWaterMark01 extends StatelessWidget {
  const MyWaterMark01({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text("全屏文字水印")),
        
        body: buildWatermark(
          child: const Center(
            child: Text(
              "我是页面内容",
              textAlign: TextAlign.center,
              style: TextStyle(fontSize: 20),
            ),
          ),
          watermarkText: "Flutter 内部资料",
        ),
      ),
    );
  }


  Widget buildWatermark({required Widget child, required String watermarkText}) {
    return Stack(
      children: [
        child,
        IgnorePointer( 
          child: Opacity(
            opacity: 0.15, 
            child: Transform.rotate(
              angle: -0.35, 
              child: Center(
                child: Text(
                  watermarkText,
                  style: const TextStyle(
                    fontSize: 32,
                    color: Colors.black,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ),
            ),
          ),
        ),
      ],
    );
  }
}
Dart 复制代码
import 'package:flutter/material.dart';

void main() {
  runApp(const MyWaterMark02());
}

class MyWaterMark02 extends StatelessWidget {
  const MyWaterMark02({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text("对角铺满水印")),
        body: FullScreenWatermark(
          content: const Center(
            child: Text("页面正常内容", style: TextStyle(fontSize: 24)),
          ),
          text: "内部专用 请勿外传",
        ),
      ),
    );
  }
}

class FullScreenWatermark extends StatelessWidget {
  final Widget content;
  final String text;

  const FullScreenWatermark({
    super.key,
    required this.content,
    required this.text,
  });

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        content,
        IgnorePointer(
          child: Opacity(
            opacity: 0.12,
            child: GridView.count(
              crossAxisCount: 3,
              childAspectRatio: 1.2,
              physics: const NeverScrollableScrollPhysics(),
              children: List.generate(30, (index) {
                return Center(
                  child: Transform.rotate(
                    angle: -0.4,
                    child: Text(
                      text,
                      style: const TextStyle(
                        fontSize: 18,
                        color: Colors.grey,
                      ),
                    ),
                  ),
                );
              }),
            ),
          ),
        ),
      ],
    );
  }
}
Dart 复制代码
import 'package:flutter/material.dart';

void main() {
  runApp(const MyWaterMark03());
}

class MyWaterMark03 extends StatelessWidget {
  const MyWaterMark03({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text("图片水印(Logo)")),
        body: ImageWatermark(
          child: Container(
            color: Colors.white,
            child: const Center(
              child: Text("主页面内容", style: TextStyle(fontSize: 24)),
            ),
          ),
        ),
      ),
    );
  }
}

class ImageWatermark extends StatelessWidget {
  final Widget child;

  const ImageWatermark({super.key, required this.child});

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        child,
        IgnorePointer(
          child: Align(
            alignment: Alignment.bottomRight, 
            child: Opacity(
              opacity: 0.4,
              child: Container(
                width: 80,
                height: 80,
                margin: const EdgeInsets.all(20),
                child: const FlutterLogo(), 
              ),
            ),
          ),
        ),
      ],
    );
  }
}
Dart 复制代码
import 'package:flutter/material.dart';

void main() => runApp(const MaterialApp(home: CustomPaintWatermark()));

class CustomPaintWatermark extends StatelessWidget {
  const CustomPaintWatermark({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("CustomPaint 水印")),
      body: Stack(
        children: [
          // 页面内容
          const Center(
            child: Text(
              "页面内容可点击",
              style: TextStyle(fontSize: 24),
            ),
          ),

         
          IgnorePointer(
            child: Container(
              width: double.infinity,
              height: double.infinity,
              color: Colors.transparent,
              child: CustomPaint(painter: WatermarkPainter()),
            ),
          ),
        ],
      ),
    );
  }
}


class WatermarkPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
   
    final textStyle = TextStyle(
      color: Colors.grey.withOpacity(0.3), 
      fontSize: 24,
      fontWeight: FontWeight.bold,
    );

    const text = "内部资料 请勿外传";

    
    for (double x = 0; x < size.width; x += 220) {
      for (double y = 0; y < size.height; y += 200) {
        canvas.save();
        canvas.translate(x, y);
        canvas.rotate(-0.3);

        final textSpan = TextSpan(text: text, style: textStyle);
        final textPainter = TextPainter(
          text: textSpan,
          textDirection: TextDirection.ltr,
        );
        textPainter.layout();
        textPainter.paint(canvas, Offset.zero);

        canvas.restore();
      }
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
相关推荐
和平宇宙1 小时前
AI笔记005. hermes-DeepSeek V4 Pro, 128K上下文引发的探索
前端·人工智能·笔记
十月的皮皮2 小时前
C语言学习笔记20260606- 求月份天数三种写法
c语言·笔记·学习
cmes_love2 小时前
Level 2逐笔成交历史数据下载方法笔记
数据库·笔记·oracle
Cloud_Shy6182 小时前
解读《Effective Python 3rd Edition》:从练气到老魔(第五章 Item 30 - 32)
开发语言·人工智能·笔记·python·学习方法
问心无愧05133 小时前
ctf show web入门110
前端·笔记
●VON3 小时前
AtomGit Flutter鸿蒙客户端:设置页面
flutter·华为·跨平台·harmonyos·鸿蒙
道一233 小时前
Windows系统查看端口占用进程的3种实用方法
windows·笔记
●VON4 小时前
AtomGit Flutter鸿蒙客户端:用户资料
flutter·华为·架构·跨平台·harmonyos·鸿蒙
悟空瞎说4 小时前
Flutter 三大主流本地存储全解:SharedPreferences、Hive、SQLite 实战指南
flutter
悟空瞎说4 小时前
Flutter Isolate 与 compute 全方位实战指南:后台任务优化,保障 UI 60 帧流畅
flutter