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

鸿蒙Next开发-添加水印以及点击穿透设置

在鸿蒙Next中,为App全局添加水印可以通过以下方式实现,其中通过窗口添加水印是一种常见且高效的方式。以下是具体方案和实现细节:


一、全局水印的实现方式

1. 窗口叠加水印(首选、推荐)

原理:在应用的主窗口(Window)上叠加一个半透明的水印层,覆盖所有页面内容。
优势:实现简单、性能较好,无需侵入业务逻辑。
实现步骤

(1) 创建全局水印组件

通过Stack布局在主页面内容上叠加水印层,通过设置hitTestBehavior(HitTestMode.Transparent)控制水印层不拦截点击事件,可结合文章<鸿蒙next开发-struct如何封装共用模块>把水印功能放到公共父模块里边去

// WatermarkComponent.ets
@Component
export struct WatermarkComponent {
  @State watermarkText: string = "水印内容" 

  build() {
    Stack() {
      // 主应用内容(通过插槽传递)
      Column() {
        Slot() // 占位符,用于承载实际页面内容
      }

      // 水印层(覆盖整个窗口)
      Flex({ direction: FlexDirection.Row, wrap: FlexWrap.Wrap }) {
        ForEach(Array(20).fill(0), (_, index) => {
          Text(this.watermarkText)
            .fontSize(16)
            .fontColor("#999999")
            .opacity(0.3)
            .rotate({ angle: -30 })
            .margin(20)
        })
      }
      .width('100%')
      .height('100%')
  .backgroundColor(Color.Transparent).hitTestBehavior(HitTestMode.Transparent)// 关键:设置水印层不拦截点击事件,否则水印下按钮点击失效。
    }
  }
}
(2) 在入口页面应用水印
// MainPage.ets
@Entry
@Component
struct MainPage {
  build() {
    WatermarkComponent() {
      // 此处放置实际页面内容
      Column() {
        Text("这是应用的主页面")
          .fontSize(24)
        // 其他组件...
      }
    }
  }
}
(3) 动态更新水印内容

可通过@State@Link实现水印动态化(如用户ID、时间戳):

@State watermarkText: string = `用户:张三 ${new Date().toLocaleString()}`

// 更新水印
updateWatermark() {
  this.watermarkText = `用户:张三 ${new Date().toLocaleString()}`
}

2. 全局悬浮窗水印

适用场景:需要跨多个Ability或独立于页面层级的水印。
实现步骤

(1) 创建悬浮窗服务
// WatermarkService.ets
import window from '@ohos.window';

export class WatermarkService {
  private static instance: WatermarkService | null = null;
  private watermarkWindow: window.Window | null = null;

  static getInstance() {
    if (!this.instance) {
      this.instance = new WatermarkService();
    }
    return this.instance;
  }

  async showWatermark() {
    try {
      this.watermarkWindow = await window.createWindow("watermark", window.WindowType.TYPE_FLOAT);
      await this.watermarkWindow.moveTo(0, 0);
      await this.watermarkWindow.resize(window.Size.FULL_SCREEN);
      await this.watermarkWindow.setTouchable(false); // 禁止交互
      await this.watermarkWindow.loadContent("pages/WatermarkPage");
      await this.watermarkWindow.show();
    } catch (err) {
      console.error('悬浮窗创建失败:', err);
    }
  }
}
(2) 初始化全局水印
// App.ets
import { WatermarkService } from './WatermarkService';

export default class App {
  onCreate() {
    WatermarkService.getInstance().showWatermark(); // 应用启动时显示水印
  }
}

3. 自定义Ability水印

适用场景:需要与业务逻辑深度绑定的动态水印。
实现步骤

// WatermarkAbility.ets
import Ability from '@ohos.application.Ability';

export default class WatermarkAbility extends Ability {
  onWindowStageCreate(windowStage) {
    windowStage.loadContent("pages/WatermarkPage", (err) => {
      if (err) console.error("水印页面加载失败:", err);
    });
  }
}

二、技术对比与选型建议

方案优点缺点适用场景
窗口叠加水印

实现简单、性能高、无额外权限

需修改页面层级结构

单Ability应用、快速集成

全局悬浮窗

跨Ability生效、独立层级

需要悬浮窗权限、性能开销略高

企业级应用、高安全需求

自定义Ability

灵活控制水印生命周期

实现复杂度高

需要动态控制水印的场景


三、安全增强技巧

  1. 防截图绕过

    // 禁止截屏(需在config.json配置权限)
    import window from '@ohos.window';
    window.getTopWindow().then(win => {
      win.setWindowPrivacyMode(true); // 开启隐私模式
    });
  2. 动态水印

    // 绑定设备信息
    import deviceInfo from '@ohos.deviceInfo';
    this.watermarkText = `设备ID: ${deviceInfo.deviceId}`;
  3. 混淆水印元素

    // 随机角度和位置
    .rotate({ angle: -30 + Math.random() * 10 })
    .position({ x: `${Math.random() * 100}%`, y: `${Math.random() * 100}%` })

四、总结

  1. 窗口叠加水印是最高效的实现方式,适合大多数场景。

  2. 若需跨Ability或更高安全级别,推荐全局悬浮窗方案

  3. 通过Stack布局和Flex组件的灵活组合,可实现高密度、动态更新的水印效果。

    关注我获取更多知识或者投稿

    16407349f8dba5693e64d54dfc7a81cf.jpeg

    4d0acd8f804e34f88a12a757064275ae.jpeg

http://www.dtcms.com/a/20197.html

相关文章:

  • c++中什么时候应该使用final关键字?
  • 143,【3】 buuctf web [GYCTF2020]EasyThinking
  • 【ISO 14229-1:2023 UDS诊断(会话控制0x10服务)测试用例CAPL代码全解析③】
  • 强化学习-NPG
  • Zbrush导入笔刷
  • 解锁电商数据宝藏:淘宝商品详情API实战指南
  • 内容中台构建高效数字化内容管理新范式
  • 【ISO 14229-1:2023 UDS诊断全量测试用例清单系列:第十三节】
  • 硬件开发笔记(三十四):AHD转MIPI国产方案详解XS9922B(一):芯片方案介绍
  • kubekey一键部署k8s高可用与kubesphere
  • 图像质量评价指标-UCIQE-UIQM
  • Ext系列文件系统
  • CAS单点登录(第7版)14.服务与应用
  • HCIA项目实践--静态路由的总结和简单配置
  • CAS单点登录(第7版)23.Webflow 管理
  • 《探秘AI绿色计算:降低人工智能硬件能耗的热点技术》
  • Atlassian工具集:Jira与Confluence集成优势、使用技巧、更新功能等
  • 【R语言】回归分析
  • C++入门小清单
  • 简要分析LeetCode树经典题目(Java)
  • vscode调试redis
  • 如何构建一个AI驱动的前端UI组件生成器
  • Streamlit与Qlib:量化投资策略可视化实战
  • 深入理解Linux网络随笔(一):内核是如何接收网络包的(上篇)
  • 【Linux】Ubuntu Linux 系统 ——PHP开发环境
  • Linux探秘坊-------5.git
  • 一种面向车载时间敏感网络的联合路由与时隙调度负载均衡算法
  • 我是农场主之在Linux中养鱼、喂牛、开火车
  • DeepSeek指导手册从入门到精通
  • langchain学习笔记之langserve服务部署