HarmonyOS ArkTS 实战:证件水印相机 从业务场景到单页应用完整解析
前言
证件水印相机 是一个基于 HarmonyOS ArkTS 与 ArkUI 声明式 UI 实现的轻量级原生应用,核心场景覆盖证件拍照、水印添加、用途标记、加密保存。它不是一个只有标题的演示页,而是把真实业务中的状态、列表、按钮、开关、提醒和说明整合在一个可运行的一屏工具里。
本文会围绕document_watermark_camera的真实代码展开,分析Index.ets如何组织状态管理、组件布局、事件响应、业务文案和编译验证。如果你正在学习 ArkTS,或者希望把一个小型生活服务/安全隐私工具拆成可复用模板,这篇文章可以直接作为项目复盘和二次开发参考。
图示说明:这里使用 HarmonyOS 官方文档配图作为结构示意,用于辅助理解页面组织方式。
推荐结合 HarmonyOS 应用开发指南、ArkTS 快速入门、ArkUI 声明式开发、ArkUI 组件总览 一起阅读。
小型工具类应用的关键不是堆功能,而是把用户打开应用后的第一眼信息、第一步操作和状态反馈做清楚。
一、项目定位与功能目标
1.1 业务定位
本项目定位为证件水印相机,目标用户打开应用后,可以快速处理证件拍照、水印添加、用途标记、加密保存相关任务。页面的重点是低学习成本:信息在一屏内完成聚合,操作结果立刻反映到状态或文案中。
1.2 功能拆解
| 功能模块 | 页面承载方式 | 用户价值 |
|---|---|---|
| 核心信息展示 | 顶部操作栏 + 证件预览工作台 + 用途按钮组 | 打开后立即理解当前状态 |
| 状态记录 | mark / saved | 让按钮、列表和文案联动 |
| 业务说明 | 说明文本与状态标签 | 降低误操作风险 |
| 操作入口 | Button、Toggle、列表点击 | 快速完成一次记录或确认 |
1.3 用户操作闭环
- 打开应用,先看顶部标题、状态或统计数字。
- 在列表、网格、侧栏或按钮组中选择当前关注项。
- 点击按钮、开关或列表项触发状态变化。
- 页面即时刷新,显示新的进度、提醒、标签或说明。
二、工程结构与入口文件
2.1 目录结构
项目核心文件集中在entry/src/main/ets/pages/Index.ets,资源名称和应用显示名则放在AppScope与entry的资源目录里。
document_watermark_camera/ AppScope/ app.json5 resources/base/element/string.json entry/ src/main/ets/pages/Index.ets src/main/resources/base/element/string.json oh-package.json52.2 页面入口
ArkUI 页面通常由@Entry与@Component标记入口组件,本项目也沿用了这种最直接的单页写法。
@Entry@Componentstruct Index{@Statemark:string='仅用于租房登记';@Statesaved:boolean=false;build(){Column(){Row(){Text('证件水印相机').fontSize(26).fontWeight(FontWeight.Bold).fontColor('#102A43').layoutWeight(1)2.3 单页应用边界
当前版本没有拆分多个页面,也没有引入服务端接口。这样做的好处是:业务逻辑集中、状态简单、编译验证快,适合用于教学、原型和小型工具交付。
三、状态模型设计
3.1 @State 字段
@State是本项目的交互核心。用户点击或切换控件后,状态变化会驱动 UI 自动刷新。
@Statemark:string='仅用于租房登记';@Statesaved:boolean=false;| 状态字段 | 作用 | 对应页面反馈 |
|---|---|---|
mark / saved | 保存当前水印用途和加密保存状态 | 影响选中态、统计数字或提示文案 |
| 本地数组 | 承载列表、标签或业务项 | 渲染 ForEach 列表和网格 |
| 布尔开关 | 控制提醒、保存或展示状态 | 切换按钮文本与颜色 |
3.2 本地数据
页面没有依赖远程接口,而是用本地数组描述业务项。这种写法适合快速搭建交互原型。
// 当前页面没有本地数组如果后续要接入真实业务系统,可以把这些数组替换成接口返回值,再保留同样的 UI 渲染结构。
四、布局结构解析
4.1 页面布局策略
本应用采用的主要布局是:顶部操作栏 + 证件预览工作台 + 用途按钮组。这种结构的好处是把标题、关键数据、业务列表和操作入口分层展示,避免所有信息挤成单调列表。
Button(this.saved?'已加密':'保存').backgroundColor(this.saved?'#2B8A3E':'#0B7285').onClick(()=>{this.saved=true})}.padding(20)Stack(){Rect().width('88%').height(300).fill('#D9E2EC').radius(8)Column(){Text('证件拍照区').fontSize(22).fontWeight(FontWeight.Bold).fontColor('#334E68')Text('ID CARD').fontSize(42).fontWeight(FontWeight.Bold).fontColor('#829AB1').margin({top:32})Text(this.mark).fontSize(20).fontColor('#C92A2A').margin({top:34})Text(this.mark).fontSize(20).fontColor('#C92A2A').margin({top:10})}}.width('100%').height(320)Row(){Button('租房登记').backgroundColor(this.mark==='仅用于租房登记'?'#0B7285':'#E6F6FF').fontColor(this.mark==='仅用于租房登记'?'#FFFFFF':'#0B7285').onClick(()=>{this.mark='仅用于租房登记'})Button('实名认证').backgroundColor(this.mark==='仅用于实名认证'?'#0B7285':'#E6F6FF').fontColor(this.mark==='仅用于实名认证'?'#FFFFFF':'#0B7285').margin({left:10}).onClick(()=>{this.mark='仅用于实名认证'})}.padding(20)4.2 组件选型
| 组件 | 使用目的 | 适合场景 |
|---|---|---|
Column | 纵向组织页面 | 标题、内容区、底部说明 |
Row | 横向排列信息 | 标题栏、统计区、操作区 |
Text | 展示标题和状态 | 关键数字、标签、说明 |
Button | 触发业务动作 | 记录、确认、推进状态 |
ForEach | 渲染数组数据 | 列表、网格、选项组 |
4.3 视觉层级
页面通过字体大小、字重、背景色和圆角区块来划分优先级:
- 顶部标题负责告诉用户当前工具是什么。
- 高亮数字或标签负责展示当前状态。
- 列表或网格负责承载业务对象。
- 底部说明负责补充风险、恢复、提醒或备注。
五、交互逻辑拆解
5.1 事件绑定
本项目的交互主要通过.onClick和.onChange完成。事件逻辑直接修改@State,从而驱动界面刷新。
Button(this.saved?'已加密':'保存').backgroundColor(this.saved?'#2B8A3E':'#0B7285').onClick(()=>{this.saved=true})Button('租房登记').backgroundColor(this.mark==='仅用于租房登记'?'#0B7285':'#E6F6FF').fontColor(this.mark==='仅用于租房登记'?'#FFFFFF':'#0B7285').onClick(()=>{this.mark='仅用于租房登记'})Button('实名认证').backgroundColor(this.mark==='仅用于实名认证'?'#0B7285':'#E6F6FF').fontColor(this.mark==='仅用于实名认证'?'#FFFFFF':'#0B7285').margin({left:10}).onClick(()=>{this.mark='仅用于实名认证'})5.2 典型操作路径
- 查看证件预览。
- 切换用途水印。
- 执行加密保存。
- 阅读本机查看提示。
5.3 状态刷新方式
ArkUI 声明式 UI 的优势在这里非常明显:不需要手动查找 DOM,也不需要额外刷新列表。只要状态变化,相关 Text、Button、背景色或条件区域会自动更新。
六、资源与应用身份配置
6.1 app.json5
每个 app 都需要独立bundleName,避免 DevEco Studio 编译或安装时与其他项目冲突。
{"app":{"bundleName":"com.example.document_watermark_camera","vendor":"example","versionCode":1000000,"versionName":"1.0.0","label":"$string:app_name"}}6.2 字符串资源
应用名通过资源文件配置,入口 Ability 标签也应保持一致。
{"string":[{"name":"app_name","value":"证件水印相机"},{"name":"EntryAbility_label","value":"证件水印相机"}]}七、代码可维护性分析
7.1 为什么适合单文件
这个项目的业务闭环较小,状态字段有限,单文件能减少学习成本。对于 CSDN 教程来说,读者可以在一个Index.ets中看到完整页面结构。
7.2 后续拆分方向
| 拆分方向 | 建议文件 | 收益 |
|---|---|---|
| 数据模型 | models/*.ets | 统一字段定义 |
| 可复用卡片 | components/*.ets | 降低布局重复 |
| 业务服务 | services/*.ets | 接入本地存储或接口 |
八、调试与编译验证
8.1 Hvigor 编译命令
在项目根目录可以使用 Hvigor 执行轻量编译验证。
hvigorw--modemodule-pmodule=entry@default assembleHap --no-daemon8.2 常见问题排查
| 问题 | 可能原因 | 解决建议 |
|---|---|---|
| ArkTS 编译失败 | 字段名与组件属性冲突 | 避免使用size、position等容易冲突的状态名 |
| 页面不刷新 | 没有使用@State | 把需要驱动 UI 的字段声明为@State |
| 真机安装失败 | 未配置签名 | 在 DevEco Studio 中开启自动签名 |
九、扩展方向
9.1 本地持久化
当前状态在内存中维护,关闭应用后不会保存。实际产品可接入 Preferences 或关系型数据库。
// 伪代码:保存关键状态// preferences.put('lastState', JSON.stringify(pageState))// preferences.flush()9.2 通知提醒
对于提醒类场景,可以结合系统通知,让用户在指定时间收到提醒。
// 伪代码:根据业务时间创建提醒// notificationManager.publish({// content: { title: '待处理提醒', text: '请回到应用确认当前任务' }// })9.3 数据校验
真实业务中应增加输入校验、空状态、异常提示和权限说明,尤其是安全隐私类工具。
总结
document_watermark_camera是一个完整但轻量的 HarmonyOS ArkTS 单页应用案例。它围绕证件水印相机的真实使用场景,把证件拍照、水印添加、用途标记、加密保存拆成状态、布局和事件三部分,让读者能从代码中理解一个小型原生应用的实现路径。
如果继续扩展,可以优先补充本地存储、通知提醒、权限说明、空状态和真机截图,这样文章和项目都会更接近完整产品形态。
如果这篇文章对你有帮助,欢迎点赞、收藏、关注,你的支持是我持续创作的动力!
相关链接:
- HarmonyOS 应用开发指南
- ArkTS 快速入门
- ArkUI 声明式开发