news 2026/7/27 9:24:41

# 备忘录应用开发实战:HarmonyOS ArkTS 快速记事本应用解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
# 备忘录应用开发实战:HarmonyOS ArkTS 快速记事本应用解析

一、应用概述

备忘录应用是移动设备上最经典、最基础的生产力工具之一。本文将以 HarmonyOS 原生开发框架 ArkTS 为基础,详细解析一个轻量级备忘录应用(Quick Memo)的完整开发过程。该应用支持用户快速记录文字内容,自动添加时间戳,并具备添加与删除备忘录的核心功能。

1.1 功能特性

  • 快速记录:用户可以在输入框中输入任意文本内容,点击添加按钮即可生成一条备忘录记录
  • 自动时间戳:每条备忘录在创建时自动记录当前时间,并按照YYYY-MM-DD HH:mm的格式呈现
  • 列表展示:所有备忘录以列表形式清晰展示,最新添加的记录排列在最上方
  • 滑动删除:支持左滑或点击删除按钮移除指定备忘录
  • 数据持久化:利用 HarmonyOS 的本地存储能力,确保重启应用后数据不丢失

1.2 适用场景

  • 日常灵感记录
  • 待办事项快速录入
  • 购物清单管理
  • 会议要点摘录

1.3 技术亮点

本应用虽然功能简洁,却完整展现了 ArkTS 声明式 UI 开发的核心理念,包括组件状态管理、列表渲染、事件绑定、数据持久化等关键技术点,是 ArkTS 入门学习的绝佳案例。


二、技术架构

2.1 整体架构概览

本应用采用 HarmonyOS 推荐的单页面(单 Ability)架构,以@Entry装饰的主页面作为唯一入口,内部通过@Component拆分为多个功能模块。整体架构分为三层:

┌─────────────────────────────────────┐ │ UI 表示层 │ │ (MainPage / MemoItem / AddMemoBar) │ ├─────────────────────────────────────┤ │ 状态管理层 │ │ (@State / @Prop / @Link 装饰器) │ ├─────────────────────────────────────┤ │ 数据持久层 │ │ (Preferences / AppStorage) │ └─────────────────────────────────────┘

2.2 核心数据结构

备忘录的数据模型定义如下:

interface Memo { id: string; // 唯一标识符 content: string; // 备忘录内容 timestamp: number; // 创建时间(时间戳) }

每个Memo对象通过id字段实现唯一标识,确保在删除和更新操作中能精确定位目标记录。timestamp字段存储 Unix 时间戳,便于后续按时间排序和格式化显示。

2.3 组件树结构

@Entry MainPage ├── Column (主容器) │ ├── Text (标题栏) │ ├── Row (输入区域) │ │ ├── TextInput (文本输入框) │ │ └── Button (添加按钮) │ └── List (备忘录列表) │ └── ForEach → MemoItem (自定义列表项) │ ├── Text (内容) │ ├── Text (时间戳) │ └── Button (删除)

三、核心代码分析

3.1 数据模型与状态管理

备忘录的数据模型使用interface定义,确保类型的强约束性。所有备忘录数据通过@State装饰器管理,当数据发生变化时,框架自动重新渲染 UI。

// 备忘录数据模型 interface Memo { id: string; content: string; timestamp: number; } @Entry @Component struct MemoApp { // 使用 @State 管理备忘录列表,驱动 UI 更新 @State private memoList: Memo[] = []; @State private inputContent: string = ''; // 格式化时间戳为可读字符串 private formatTime(timestamp: number): string { const date = new Date(timestamp); const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); const hour = String(date.getHours()).padStart(2, '0'); const minute = String(date.getMinutes()).padStart(2, '0'); return `${year}-${month}-${day} ${hour}:${minute}`; } }

@State是 ArkTS 中最基础的状态装饰器。当memoList的内容发生变化(增删改)时,所有依赖于该数据的 UI 组件会自动重新渲染。这种声明式编程方式大幅简化了传统的命令式 DOM 操作,让开发者可以专注于业务逻辑本身。

3.2 添加备忘录功能

备忘录的添加操作需要完成三步工作:生成唯一 ID、获取当前时间戳、将新记录插入列表头部。

// 添加备忘录 addMemo() { if (this.inputContent.trim() === '') { // 空内容不添加,提升用户体验 return; } // 生成唯一 ID const newMemo: Memo = { id: Date.now().toString() + Math.random().toString(36).substr(2, 9), content: this.inputContent.trim(), timestamp: Date.now() }; // 插入到列表头部(最新在上) this.memoList.unshift(newMemo); // 清空输入框 this.inputContent = ''; // 持久化存储 this.saveData(); }

关键设计考量

  • ID 生成策略:使用Date.now()结合随机数,确保在多设备、多线程环境下 ID 的唯一性
  • 空值校验:在添加前校验内容是否为空,避免产生无意义的空记录
  • 头部插入:使用unshift而非push,保证最新记录显示在列表最上方
  • 自动清空:添加成功后立即清空输入框,方便用户连续记录

3.3 删除备忘录功能

删除操作提供两种交互方式:点击删除按钮和左滑删除手势。

// 删除备忘录 deleteMemo(memoId: string) { // 根据 ID 过滤出要保留的记录 this.memoList = this.memoList.filter(item => item.id !== memoId); // 同步持久化数据 this.saveData(); } // UI 中的删除按钮 Button('删除') .fontColor(Color.Red) .fontSize(14) .onClick(() => { this.deleteMemo(item.id); })

使用数组的filter方法删除记录是一种函数式编程的实践,它不会修改原数组,而是返回一个新数组。ArkTS 的状态管理机制能检测到这种变化并触发 UI 更新。

3.4 列表渲染与 ForEach

备忘录列表使用ForEach指令进行循环渲染,这是 ArkTS 中最常用的列表渲染方式。

List({ space: 12 }) { ForEach(this.memoList, (item: Memo, index: number) => { ListItem() { // 自定义备忘录卡片 Column() { Text(item.content) .fontSize(16) .fontWeight(FontWeight.Medium) .width('100%') .textAlign(TextAlign.Start) Text(this.formatTime(item.timestamp)) .fontSize(12) .fontColor(Color.Gray) .width('100%') .textAlign(TextAlign.End) .margin({ top: 8 }) // 删除按钮 Button('删除') .fontColor(Color.Red) .fontSize(14) .onClick(() => { this.deleteMemo(item.id); }) .alignSelf(ItemAlign.End) .margin({ top: 4 }) } .padding(16) .backgroundColor(Color.White) .borderRadius(12) .shadow({ radius: 4, color: 'rgba(0, 0, 0, 0.08)', offsetX: 0, offsetY: 2 }) .width('100%') } // 添加滑动删除支持 .swipeAction({ end: { builder: () => { Button('删除') .width(80) .height('100%') .backgroundColor(Color.Red) .fontColor(Color.White) .onClick(() => { this.deleteMemo(item.id); }) } } }) }, (item: Memo) => item.id) }

ForEach 的 key 生成器:第三个参数(item: Memo) => item.id是 key 生成器,它告诉框架如何唯一标识每个列表项。使用item.id作为 key 可以确保列表在增删操作时能够高效地复用和重排组件,避免不必要的全量重建。

3.5 数据持久化

利用 HarmonyOS 的 Preferences 轻量级键值数据库实现数据持久化:

import preferences from '@ohos.data.preferences'; // 保存数据到本地 async saveData() { const context = getContext(this); const pref = await preferences.getPreferences(context, 'memo_db'); // 将对象数组转换为 JSON 字符串存储 await pref.put('memo_list', JSON.stringify(this.memoList)); await pref.flush(); } // 从本地加载数据 async loadData() { const context = getContext(this); const pref = await preferences.getPreferences(context, 'memo_db'); const jsonStr = await pref.get('memo_list', '[]'); this.memoList = JSON.parse(jsonStr as string); }

持久化流程

  1. 通过getPreferences获取或创建数据库实例
  2. 使用put方法存储序列化后的数据
  3. 调用flush确保数据写入磁盘
  4. 读取时使用get方法获取 JSON 字符串,再反序列化为对象数组

四、HarmonyOS关键技术应用

4.1 声明式 UI 与状态管理

HarmonyOS 的 ArkUI 框架采用了声明式 UI 范式,这与传统的命令式 UI 有本质区别。在声明式 UI 中,开发者只需描述 UI 的最终状态,框架负责处理状态变化后的 UI 更新。

特性传统命令式声明式(ArkTS)
编程方式手动操作 DOM描述 UI 状态
状态同步手动同步自动追踪
代码量较多精简
可维护性一般优秀

@State 装饰器是状态管理的核心,其工作原理可概括为:

  1. 开发者用@State标记一个变量为响应式数据
  2. 当该变量的值发生变化时,框架自动标记所有依赖它的组件为"脏"状态
  3. 框架在下一个渲染周期中,重新执行所有脏组件的build方法
  4. 通过虚拟 DOM 的 diff 算法,仅更新实际变化的 UI 部分

4.2 List 组件的性能优化

List组件是 HarmonyOS 中高效的列表容器,它内置了以下优化机制:

  • 懒加载(Lazy Loading):只渲染可见区域的列表项,不可见区域的内容不会创建对应的组件实例
  • 组件复用(Component Reuse):当用户滚动列表时,移出屏幕的组件实例会被回收并复用给新进入屏幕的列表项
  • 缓存池(Cache Pool):在可见区域上下各预缓存一定数量的列表项,确保快速滚动时的流畅体验
List({ space: 12, scroller: this.scroller }) { // 列表内容 } .layoutWeight(1) .listDirection(Axis.Vertical) .edgeEffect(EdgeEffect.Spring) .scrollBar(BarState.Off)

4.3 自定义组件封装

将备忘录卡片封装为独立的@Component,提升了代码的复用性和可维护性:

@Component struct MemoItem { private memo: Memo; private onDelete: () => void; build() { Column() { Text(this.memo.content) .fontSize(16) .fontWeight(FontWeight.Medium) Text(this.formatTime(this.memo.timestamp)) .fontSize(12) .fontColor(Color.Gray) .margin({ top: 8 }) Button('删除') .fontColor(Color.Red) .fontSize(14) .onClick(() => { this.onDelete(); }) } .padding(16) .backgroundColor(Color.White) .borderRadius(12) } private formatTime(timestamp: number): string { // 时间格式化逻辑 } }

自定义组件的优势:

  • 封装性:将 UI 结构和样式封装在组件内部,对外只暴露必要的属性和回调
  • 复用性:同一组件可在不同页面或同一页面的不同位置重复使用
  • 可测试性:独立组件便于进行单元测试和 UI 测试

五、UI设计与交互

5.1 视觉设计

本应用的视觉设计遵循 Material Design 设计规范,同时融入 HarmonyOS 的设计语言特点:

配色方案

  • 主色调:系统蓝色(#0A59F7
  • 背景色:浅灰色(#F5F5F5
  • 卡片背景:纯白色(#FFFFFF
  • 文字色:深灰色(#333333
  • 辅助色:灰色(#999999)用于时间戳
  • 警示色:红色(#FF0000)用于删除操作

卡片设计

每条备忘录以卡片形式呈现,圆角 12px,带有微弱的阴影效果,营造出层次感和立体感。卡片内左上方显示备忘录内容,右下方显示创建时间,布局清晰直观。

5.2 交互反馈

  • 添加动画:新备忘录添加时,列表项以淡入动画呈现
  • 删除反馈:删除按钮点击后,列表项以淡出动画消失
  • 滑动删除:列表项支持左滑手势,露出删除按钮,提升操作效率
  • 空状态提示:当列表为空时,显示"暂无备忘录"的友好提示

5.3 自适应布局

应用使用 ArkTS 的弹性布局(FlexColumn)实现自适应,在不同屏幕尺寸下均有良好表现。

Column() { // 标题区域 Text('备忘录') .fontSize(24) .fontWeight(FontWeight.Bold) .width('100%') .padding(16) // 输入区域 Row() { TextInput({ placeholder: '输入备忘录内容...' }) .layoutWeight(1) .height(48) .backgroundColor(Color.White) .borderRadius(8) Button('添加') .width(64) .height(48) .margin({ left: 12 }) .backgroundColor('#0A59F7') .fontColor(Color.White) .borderRadius(8) } .padding({ left: 16, right: 16, bottom: 12 }) // 列表区域 List({ space: 12 }) { // ... } .layoutWeight(1) .padding(16) } .width('100%') .height('100%') .backgroundColor('#F5F5F5')

六、性能优化与最佳实践

6.1 性能优化策略

6.1.1 减少不必要的重新渲染

在使用@State时,需要注意避免触发不必要的 UI 更新:

// ❌ 不良实践:每次添加都触发全列表重绘 this.memoList = [...this.memoList, newMemo]; // ✅ 最佳实践:使用数组方法并配合 key 生成器 this.memoList.unshift(newMemo); // ForEach 配合唯一 key 可精确定位需要更新的项
6.1.2 合理使用计算属性

对于需要复杂计算的数据,使用@Computed或 getter 方法缓存计算结果:

// 使用 getter 计算统计数据 get totalMemos(): number { return this.memoList.length; } get todayMemos(): number { const today = new Date().toDateString(); return this.memoList.filter(item => new Date(item.timestamp).toDateString() === today ).length; }
6.1.3 数据持久化优化

避免频繁的磁盘写入操作,可以采用防抖(Debounce)策略:

private saveTimer: number | null = null; debounceSave() { if (this.saveTimer) { clearTimeout(this.saveTimer); } this.saveTimer = setTimeout(() => { this.saveData(); this.saveTimer = null; }, 500); // 500ms 防抖 }

6.2 最佳实践总结

6.2.1 代码组织规范
src/ ├── main/ │ ├── ets/ │ │ ├── pages/ │ │ │ └── Index.ets # 主页面 │ │ ├── components/ │ │ │ ├── MemoItem.ets # 备忘录卡片组件 │ │ │ └── AddMemoBar.ets # 添加栏组件 │ │ ├── model/ │ │ │ └── MemoModel.ets # 数据模型定义 │ │ └── utils/ │ │ └── DateUtil.ets # 工具函数 │ └── resources/ │ └── ...
6.2.2 状态提升原则

将共享状态提升到共同的父组件中,子组件通过@Prop@Link接收数据和回调:

// 父组件管理状态 @State memoList: Memo[] = []; build() { Column() { AddMemoBar({ onAdd: (content) => this.addMemo(content) }) MemoList({ memos: this.memoList, onDelete: (id) => this.deleteMemo(id) }) } }
6.2.3 错误处理与边界情况
// 处理空列表情况 if (this.memoList.length === 0) { // 显示空状态 Image($r('app.media.empty_illustration')) .width(200) .height(200) Text('暂无备忘录') .fontColor(Color.Gray) .fontSize(16) } // 处理输入过长的情况 if (this.inputContent.length > 500) { showToast('备忘录内容不能超过500字'); return; }

七、总结与扩展思路

7.1 项目总结

本文详细解析了基于 HarmonyOS ArkTS 框架开发的备忘录应用。通过本项目的学习,开发者可以掌握以下关键技术点:

  1. ArkTS 声明式 UI 开发:理解@State@Prop@Link等装饰器的工作原理和使用场景
  2. 列表渲染与交互:掌握List+ForEach的高效列表渲染方案
  3. 数据持久化:熟悉 HarmonyOS Preferences 轻量级数据库的使用
  4. 自定义组件设计:学会将 UI 拆分为可复用的自定义组件
  5. 交互体验优化:掌握动画、手势、反馈等交互设计要点

7.2 扩展思路

本应用作为基础版本,可以从以下几个方面进行扩展和增强:

7.2.1 功能增强
  • 分类管理:为备忘录添加分类标签,支持按分类筛选
  • 搜索功能:实现关键词搜索,快速定位目标记录
  • 富文本编辑:支持 Markdown 语法或富文本格式
  • 图片附件:支持为备忘录添加图片或语音附件
  • 云同步:利用 HarmonyOS 的分布式能力实现多设备数据同步
7.2.2 交互升级
  • 长按拖拽排序:通过拖拽手势改变备忘录顺序
  • 暗黑模式适配:响应系统暗黑模式,提供舒适的夜间使用体验
  • 小组件(Widget):开发 HarmonyOS 卡片小组件,在桌面直接查看和添加备忘录
  • 语音输入:集成语音识别能力,支持语音转文字记录
7.2.3 技术进阶
  • 原子化服务:将应用改造为 HarmonyOS 原子化服务,免安装即用
  • 跨端移植:利用 ArkTS 的多平台适配能力,将应用移植到平板和折叠屏设备
  • 性能监控:接入性能监控 SDK,持续优化应用性能
  • 单元测试:为关键业务逻辑编写单元测试,确保代码质量

7.3 学习建议

对于 HarmonyOS 初学者,建议按照以下路径学习本应用相关的技术点:

  1. 先理解@State状态管理机制,这是 ArkTS 开发的核心
  2. 掌握List组件的使用,包括懒加载和组件复用
  3. 学习ForEach的 key 生成器原理
  4. 理解自定义组件的生命周期和通信方式
  5. 最后研究数据持久化和性能优化方案

通过本项目的学习,开发者可以建立起 ArkTS 应用开发的基本框架思维,为进一步开发更复杂的 HarmonyOS 应用打下坚实基础。


项目代码已完整开源,开发者可以基于本文的代码示例进行二次开发和创新。HarmonyOS 生态正快速发展,掌握 ArkTS 开发技能将为开发者打开通往万物互联时代的大门。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/27 9:15:32

Trace驱动仿真

Trace 驱动(Trace-Driven)仿真模型是计算机体系结构领域一类把"工作负载执行"和"架构模型推演"在时间上和空间上都拆开的方法:先用插桩/功能模拟把程序跑一遍,录下它"干了什么"(指令流、…

作者头像 李华
网站建设 2026/7/27 9:12:22

合成数据与差分隐私:破解测试数据合规难题的工程实践

1. 项目概述:当数据成为“烫手山芋”,合规测试如何破局? 在数字化转型的浪潮中,数据是驱动业务创新的核心燃料,但同时也成了悬在企业头顶的“达摩克利斯之剑”。无论是金融风控、医疗诊断还是电商推荐,开发…

作者头像 李华
网站建设 2026/7/27 9:08:56

HarmonyOS 沉浸光感动效实战:转场、光影变化与性能兜底

HarmonyOS 沉浸光感动效实战:转场、光影变化与性能兜底 沉浸光感一旦加入动效,问题会比静态页面更明显:页面转场拖沓,Tab 切换时背景和卡片一起动,光影变化过强让用户眩晕,弱设备上掉帧,用户开启…

作者头像 李华
网站建设 2026/7/27 9:08:01

Codex服务端上下文压缩:原理、优势与工程实践指南

最近在折腾几个大模型项目时,我又遇到了那个老问题——上下文太长导致响应变慢、成本飙升。试了几个第三方压缩框架,效果总是不尽如人意,要么压缩率不够,要么关键信息丢失严重。直到把目光转回服务端原生的上下文压缩方案&#xf…

作者头像 李华
网站建设 2026/7/27 9:06:37

GS-Agent:生成式多智能体物理仿真环境搭建与优化指南

1. 先搞清楚 GS-Agent 到底解决什么物理仿真痛点如果你做过物理仿真或多智能体模拟项目,大概率遇到过这些问题:手动搭建测试场景耗时太长、环境参数调整不够灵活、多智能体交互逻辑需要反复调试。GS-Agent 的核心价值在于用生成式仿真思路自动化构建 4D …

作者头像 李华
网站建设 2026/7/27 8:59:48

从物理模拟到世界模型,具身智能机器人如何练就真实世界的常识

文章目录 每日一句正能量 构建机器人的“物理直觉”:三位一体的认知飞轮 物理实践与高保真模拟:跨越 Sim-to-Real 的鸿沟 世界模型:从记忆场景到推演规律 因果推断与可微分仿真:迈向鲁棒决策的新范式 每日一句正能量 当你自带光芒,无需追逐,美好的一切都会不请自来。 追逐…

作者头像 李华