
一、应用概述
随手记备忘录小应用是一款基于HarmonyOS ArkUI框架开发的轻量级待办事项管理工具。在快节奏的现代生活中,人们经常需要记录各种琐事、提醒事项和临时想法,传统的纸质备忘录容易丢失且不便管理,而手机自带的备忘录应用往往功能过于复杂。本应用旨在提供一个简洁、高效、易用的备忘录解决方案,让用户能够快速记录、查看和管理日常事务。
1.1 应用定位
随手记备忘录定位于"极简主义"工具应用,核心设计理念是"少即是多"。应用摒弃了繁杂的分类、标签、提醒等功能,专注于最核心的"记录"和"管理"两个操作。这种设计理念使得用户可以在几秒钟内完成一条备忘录的添加或删除,极大地提升了使用效率。
1.2 目标用户群体
- 忙碌的上班族:需要快速记录会议时间、待办事项、临时任务
- 学生群体:记录作业截止日期、考试安排、社团活动
- 家庭主妇:记录购物清单、家务安排、家庭事务
- 老年人群体:简单的操作界面,无需复杂学习成本
1.3 核心功能特性
| 功能模块 | 功能描述 | 技术实现 |
|---|
| 快速输入 | 提供输入框供用户输入备忘内容 | TextInput组件 |
| 一键添加 | 点击按钮即可添加新备忘录 | Button组件 |
| 列表展示 | 以列表形式展示所有备忘录条目 | List + ForEach组件 |
| 单条删除 | 每条备忘录可单独删除 | Button + filter方法 |
| 实时更新 | 数据变化后界面自动刷新 | @State状态管理 |
1.4 应用界面预览
应用界面采用经典的垂直布局结构,从上到下依次为:
- 顶部导航栏:包含返回按钮和应用标题,采用浅灰色背景
- 输入区域:包含输入框和添加按钮,是用户的主要操作区
- 列表区域:展示所有备忘录条目,支持滚动浏览
二、技术架构设计
2.1 整体架构图
┌─────────────────────────────────────────────────────────────┐
│ MemoApp 组件 │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 状态管理层 (@State) │ │
│ │ ┌─────────────────┐ ┌──────────────────────────┐ │ │
│ │ │ inputText_1 │ │ memos_1[] │ │ │
│ │ │ (输入内容) │ │ (备忘录数组) │ │ │
│ │ └─────────────────┘ └──────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 视图层 (build方法) │ │
│ │ ┌───────────────────────────────────────────────┐ │ │
│ │ │ Row (导航栏) │ │ │
│ │ │ ├── Button (返回) │ │ │
│ │ │ └── Text (标题) │ │ │
│ │ └───────────────────────────────────────────────┘ │ │
│ │ ┌───────────────────────────────────────────────┐ │ │
│ │ │ Column (内容区) │ │ │
│ │ │ ├── TextInput (输入框) │ │ │
│ │ │ ├── Button (添加按钮) │ │ │
│ │ │ ├── Text (列表标题) │ │ │
│ │ │ └── List (备忘录列表) │ │ │
│ │ │ └── ForEach → ListItem → Row │ │ │
│ │ └───────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
2.2 数据流设计
本应用采用单向数据流架构,数据从状态层流向视图层,用户操作触发状态更新,进而驱动视图刷新:
用户输入 → onChange回调 → 更新inputText_1状态
↓
点击添加按钮 → 验证输入 → 更新memos_1数组 → 触发UI刷新
↓
点击删除按钮 → filter过滤 → 更新memos_1数组 → 触发UI刷新
2.3 组件层级关系
Column (根容器)
├── Row (导航栏容器)
│ ├── Button (返回按钮)
│ └── Text (应用标题)
└── Column (内容容器)
├── TextInput (输入框组件)
├── Button (添加按钮组件)
├── Text (列表标题)
└── List (列表容器)
└── ForEach (循环渲染)
└── ListItem (列表项容器)
└── Row (列表项布局)
├── Text (备忘内容)
└── Button (删除按钮)
2.4 技术选型说明
| 技术点 | 选择方案 | 选择理由 |
|---|
| 开发语言 | ArkTS | HarmonyOS官方推荐,强类型支持,编译时检查 |
| UI框架 | ArkUI声明式 | 代码简洁,状态驱动,易于维护 |
| 状态管理 | @State装饰器 | 轻量级,适合简单应用,自动触发UI刷新 |
| 列表渲染 | List + ForEach | 高性能,支持滚动,自动回收不可见项 |
| 路由导航 | router API | 官方推荐,支持页面跳转和返回 |
三、核心组件详解
3.1 TextInput组件深度解析
TextInput是用户输入的核心组件,在本应用中承担着接收用户备忘内容的重要职责。
3.1.1 基础属性配置
TextInput({ placeholder: '写下你想记的事情...' })
.width('90%')
.height(48)
.margin({ top: 20 })
.onChange((value_1: string) => {
this.inputText_1 = value_1;
})
3.1.2 TextInput属性详解表
| 属性名 | 类型 | 默认值 | 说明 |
|---|
| placeholder | string | - | 输入框为空时显示的提示文本 |
| width | Length | - | 输入框宽度,支持数字、百分比、字符串 |
| height | Length | - | 输入框高度 |
| margin | Margin | - | 外边距,可设置top/bottom/left/right |
| type | InputType | Normal | 输入类型,如Normal/Password/Email等 |
| maxLength | number | - | 最大输入字符数限制 |
| enterKeyType | EnterKeyType | Done | 回车键类型,如Done/Search/Go等 |
| caretColor | ResourceColor | - | 光标颜色 |
| placeholderColor | ResourceColor | - | 占位符文本颜色 |
| placeholderFont | Font | - | 占位符文本字体样式 |
3.1.3 TextInput事件处理
TextInput({ placeholder: '请输入内容' })
.onChange((value: string) => {
console.log('输入内容变化:' + value);
})
.onSubmit(() => {
console.log('用户按下回车键');
})
.onEditChanged((isEditing: boolean) => {
console.log('编辑状态:' + isEditing);
})
.onTouch((event: TouchEvent) => {
if (event.type === TouchType.Press) {
console.log('输入框被按下');
}
})
3.1.4 TextInput样式定制
TextInput({ placeholder: '写下你想记的事情...' })
.width('90%')
.height(48)
.margin({ top: 20 })
.backgroundColor('#F5F5F5')
.borderRadius(8)
.border({ width: 1, color: '#E0E0E0' })
.padding({ left: 16, right: 16 })
.fontColor('#333333')
.fontSize(16)
.fontWeight(FontWeight.Normal)
.onChange((value_1: string) => {
this.inputText_1 = value_1;
})
3.2 Button组件深度解析
Button组件是用户交互的核心入口,在本应用中用于添加备忘录和删除备忘录两个场景。
3.2.1 添加按钮实现
Button('添加')
.width('90%')
.height(40)
.margin({ top: 12 })
.backgroundColor('#0A59F7')
.fontColor('#FFFFFF')
.fontSize(16)
.fontWeight(FontWeight.Medium)
.borderRadius(8)
.onClick(() => {
if (this.inputText_1 !== '') {
this.memos_1 = this.memos_1.concat([this.inputText_1]);
this.inputText_1 = '';
}
})
3.2.2 Button属性详解表
| 属性名 | 类型 | 默认值 | 说明 |
|---|
| label | string | - | 按钮显示文本 |
| width | Length | - | 按钮宽度 |
| height | Length | - | 按钮高度 |
| backgroundColor | ResourceColor | - | 背景颜色 |
| fontColor | ResourceColor | - | 文字颜色 |
| fontSize | Length | - | 字体大小 |
| fontWeight | FontWeight | Normal | 字体粗细 |
| borderRadius | Length | - | 圆角半径 |
| type | ButtonType | Capsule | 按钮类型:Capsule/Circle/Normal |
| stateEffect | boolean | true | 是否开启按压效果 |
3.2.3 Button事件处理
Button('添加')
.onClick(() => {
console.log('按钮被点击');
})
.onTouch((event: TouchEvent) => {
if (event.type === TouchType.Press) {
console.log('按钮被按下');
} else if (event.type === TouchType.Up) {
console.log('按钮被释放');
}
})
.onAppear(() => {
console.log('按钮已挂载');
})
.aboutToDisappear(() => {
console.log('按钮即将卸载');
})
3.2.4 删除按钮实现
Button('删除')
.width(60)
.height(32)
.fontSize(12)
.backgroundColor('#FF3B30')
.fontColor('#FFFFFF')
.borderRadius(4)
.onClick(() => {
this.memos_1 = this.memos_1.filter((_, i_1: number) => i_1 !== index_1);
})
3.3 List组件深度解析
List组件是展示备忘录列表的核心容器,具有高性能的滚动和回收机制。
3.3.1 List基础用法
List() {
ForEach(this.memos_1, (item_1: string, index_1: number) => {
ListItem() {
Row() {
Text(item_1)
.fontSize(14)
.layoutWeight(1)
Button('删除')
.width(60)
.height(32)
.fontSize(12)
.backgroundColor('#FF3B30')
.onClick(() => {
this.memos_1 = this.memos_1.filter((_, i_1: number) => i_1 !== index_1);
})
}
.padding(12)
.width('100%')
}
})
}
.width('90%')
.margin({ top: 8 })
3.3.2 List属性详解表
| 属性名 | 类型 | 默认值 | 说明 |
|---|
| width | Length | - | 列表宽度 |
| height | Length | - | 列表高度 |
| divider | Divider | - | 列表项分割线样式 |
| scrollBar | BarState | Off | 滚动条状态:On/Off/Auto |
| edgeEffect | EdgeEffect | Spring | 边缘滑动效果:Spring/Fade/None |
| layoutDirection | Axis | Vertical | 滚动方向:Vertical/Horizontal |
| chainAnimationOptions | ChainAnimationOptions | - | 链式动画配置 |
3.3.3 List事件处理
List() {
}
.onScroll((scrollOffset: number, scrollState: ScrollState) => {
console.log('滚动偏移量:' + scrollOffset);
})
.onScrollEdge((side: Edge) => {
console.log('滚动到边缘:' + side);
})
.onScrollStop(() => {
console.log('滚动停止');
})
.onItemClick((item: Object, index: number) => {
console.log('点击了第' + index + '项');
})
3.4 ForEach组件深度解析
ForEach是ArkUI中用于循环渲染的核心组件,能够根据数组数据动态生成列表项。
3.4.1 ForEach基础语法
ForEach(
this.memos_1,
(item_1: string, index_1: number) => {
ListItem() {
}
},
(item_1: string, index_1: number) => {
return index_1.toString();
}
)
3.4.2 ForEach参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|
| arr | Array | 是 | 数据源数组 |
| itemGenerator | (item: any, index?: number) => void | 是 | 列表项生成函数 |
| keyGenerator | (item: any, index?: number) => string | 否 | 键值生成函数,用于优化渲染 |
3.4.3 ForEach性能优化
ForEach(
this.memos_1,
(item_1: string, index_1: number) => {
ListItem() {
}
},
(item_1: string, index_1: number) => {
return 'memo_' + index_1;
}
)
ForEach(this.memos_1, (item_1: string) => {
ListItem() {
}
})
四、状态管理详解
4.1 @State装饰器原理
@State是ArkUI中最基础的状态管理装饰器,被装饰的变量称为状态变量。当状态变量的值发生变化时,ArkUI框架会自动检测变化并触发UI组件的重新渲染。
@State inputText_1: string = '';
@State memos_1: string[] = [
'记得买牛奶',
'明天开会',
'周末去公园',
'给妈妈打电话'
];
4.2 状态变量的特点
| 特点 | 说明 | 示例 |
|---|
| 响应式 | 变量变化自动触发UI更新 | this.inputText_1 = '新值' |
| 类型安全 | 必须指定明确的类型 | @State count: number = 0 |
| 初始化 | 必须提供初始值 | @State name: string = '' |
| 私有性 | 只能在当前组件内访问 | 不能被外部组件直接修改 |
4.3 状态更新机制
4.3.1 基本类型状态更新
this.inputText_1 = '新的备忘内容';
@State count: number = 0;
this.count = this.count + 1;
@State isVisible: boolean = true;
this.isVisible = false;
4.3.2 数组类型状态更新
this.memos_1 = this.memos_1.concat(['新备忘录']);
this.memos_1 = this.memos_1.filter((_, i) => i !== index);
this.memos_1 = [...this.memos_1, '新备忘录'];
this.memos_1.push('新备忘录');
4.4 状态更新流程图
用户操作
↓
触发事件处理函数
↓
修改@State变量
↓
ArkUI框架检测变化
↓
标记需要更新的组件
↓
重新执行build方法
↓
生成新的虚拟DOM树
↓
与旧虚拟DOM树对比
↓
计算最小更新差异
↓
应用到实际DOM
↓
UI完成更新
4.5 状态管理最佳实践
4.5.1 数组操作规范
addMemo(content: string) {
this.memos_1 = [...this.memos_1, content];
}
removeMemo(index: number) {
this.memos_1 = this.memos_1.filter((_, i) => i !== index);
}
addMemo(content: string) {
this.memos_1.push(content);
}
removeMemo(index: number) {
this.memos_1.splice(index, 1);
}
4.5.2 状态变量命名规范
@State inputText_1: string = '';
@State memos_1: string[] = [];
@State input: string = '';
@State list: string[] = [];
五、UI布局实现详解
5.1 整体布局结构
本应用采用Column作为根容器,内部嵌套Row和Column实现复杂的布局结构。
Column() {
Row() {
Button('返回')
.onClick(() => router.back())
Text('随手记备忘录小应用')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.layoutWeight(1)
.textAlign(TextAlign.Center)
}
.width('100%')
.padding(12)
.backgroundColor('#F1F3F5')
Column() {
TextInput({ placeholder: '写下你想记的事情...' })
.width('90%')
.height(48)
.margin({ top: 20 })
.onChange((value_1: string) => {
this.inputText_1 = value_1;
})
Button('添加')
.width('90%')
.height(40)
.margin({ top: 12 })
.backgroundColor('#0A59F7')
.onClick(() => {
if (this.inputText_1 !== '') {
this.memos_1 = this.memos_1.concat([this.inputText_1]);
this.inputText_1 = '';
}
})
Text('备忘录列表')
.fontSize(16)
.fontWeight(FontWeight.Medium)
.margin({ top: 24, left: 20 })
.width('90%')
List() {
ForEach(this.memos_1, (item_1: string, index_1: number) => {
ListItem() {
Row() {
Text(item_1)
.fontSize(14)
.layoutWeight(1)
Button('删除')
.width(60)
.height(32)
.fontSize(12)
.backgroundColor('#FF3B30')
.onClick(() => {
this.memos_1 = this.memos_1.filter((_, i_1: number) => i_1 !== index_1);
})
}
.padding(12)
.width('100%')
}
})
}
.width('90%')
.margin({ top: 8 })
}
.width('100%')
.layoutWeight(1)
}
.width('100%')
.height('100%')
.backgroundColor('#FFFFFF')
5.2 布局属性详解
5.2.1 尺寸属性
| 属性 | 类型 | 说明 | 示例 |
|---|
| width | Length | 组件宽度 | .width('90%') 或 .width(200) |
| height | Length | 组件高度 | .height(48) |
| size | SizeOptions | 同时设置宽高 | .size({ width: 200, height: 100 }) |
5.2.2 间距属性
| 属性 | 类型 | 说明 | 示例 |
|---|
| margin | Margin | 外边距 | .margin({ top: 20, left: 10 }) |
| padding | Padding | 内边距 | .padding(12) 或 .padding({ left: 16, right: 16 }) |
5.2.3 权重属性
Row() {
Text('标题')
.layoutWeight(1)
Button('操作')
.width(60)
}
Column() {
Text('头部')
.height(50)
List()
.layoutWeight(1)
Text('底部')
.height(50)
}
5.3 布局容器对比
| 容器 | 布局方向 | 特点 | 适用场景 |
|---|
| Column | 垂直 | 子组件从上到下排列 | 页面主体、垂直列表 |
| Row | 水平 | 子组件从左到右排列 | 导航栏、工具栏、列表项 |
| Stack | 层叠 | 子组件堆叠显示 | 覆盖层、徽章、水印 |
| Flex | 弹性 | 支持换行、对齐方式 | 复杂布局、响应式布局 |
| List | 列表 | 高性能滚动、自动回收 | 长列表、数据展示 |
六、样式定制详解
6.1 颜色规范
本应用采用了HarmonyOS设计规范中的推荐颜色:
| 用途 | 颜色值 | 说明 |
|---|
| 主色调 | #0A59F7 | HarmonyOS主题蓝,用于主要操作按钮 |
| 危险操作 | #FF3B30 | 红色,用于删除等危险操作 |
| 背景色 | #FFFFFF | 白色,主内容区背景 |
| 导航栏背景 | #F1F3F5 | 浅灰色,区分导航区域 |
| 文字主色 | #333333 | 深灰色,主要文字内容 |
| 文字辅色 | #666666 | 中灰色,次要文字内容 |
6.2 字体规范
Text('随手记备忘录小应用')
.fontSize(20)
.fontWeight(FontWeight.Bold)
Text('备忘录列表')
.fontSize(16)
.fontWeight(FontWeight.Medium)
Text(item_1)
.fontSize(14)
.fontWeight(FontWeight.Normal)
Button('删除')
.fontSize(12)
6.3 圆角规范
Button('添加')
.borderRadius(8)
TextInput({ placeholder: '写下你想记的事情...' })
.borderRadius(8)
Row() {
}
.borderRadius(4)
6.4 间距规范
| 元素 | margin | padding | 说明 |
|---|
| 导航栏 | - | 12 | 导航栏内边距 |
| 输入框 | top: 20 | - | 输入框顶部间距 |
| 添加按钮 | top: 12 | - | 按钮顶部间距 |
| 列表标题 | top: 24, left: 20 | - | 标题间距 |
| 列表项 | - | 12 | 列表项内边距 |
七、完整代码示例
7.1 完整源代码
import { router } from '@kit.ArkUI';
@Entry
@Component
struct MemoApp {
@State inputText_1: string = '';
@State memos_1: string[] = [
'记得买牛奶',
'明天开会',
'周末去公园',
'给妈妈打电话'
];
build() {
Column() {
Row() {
Button('返回')
.onClick(() => router.back())
Text('随手记备忘录小应用')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.layoutWeight(1)
.textAlign(TextAlign.Center)
}
.width('100%')
.padding(12)
.backgroundColor('#F1F3F5')
Column() {
TextInput({ placeholder: '写下你想记的事情...' })
.width('90%')
.height(48)
.margin({ top: 20 })
.onChange((value_1: string) => {
this.inputText_1 = value_1;
})
Button('添加')
.width('90%')
.height(40)
.margin({ top: 12 })
.backgroundColor('#0A59F7')
.onClick(() => {
if (this.inputText_1 !== '') {
this.memos_1 = this.memos_1.concat([this.inputText_1]);
this.inputText_1 = '';
}
})
Text('备忘录列表')
.fontSize(16)
.fontWeight(FontWeight.Medium)
.margin({ top: 24, left: 20 })
.width('90%')
List() {
ForEach(this.memos_1, (item_1: string, index_1: number) => {
ListItem() {
Row() {
Text(item_1)
.fontSize(14)
.layoutWeight(1)
Button('删除')
.width(60)
.height(32)
.fontSize(12)
.backgroundColor('#FF3B30')
.onClick(() => {
this.memos_1 = this.memos_1.filter((_, i_1: number) => i_1 !== index_1);
})
}
.padding(12)
.width('100%')
}
})
}
.width('90%')
.margin({ top: 8 })
}
.width('100%')
.layoutWeight(1)
}
.width('100%')
.height('100%')
.backgroundColor('#FFFFFF')
}
}
7.2 代码结构说明
| 代码区域 | 行数 | 功能说明 |
|---|
| 导入语句 | 1 | 导入router模块 |
| 组件声明 | 3-5 | 定义MemoApp组件 |
| 状态变量 | 6-13 | 定义输入内容和备忘录数组 |
| 导航栏 | 16-25 | 返回按钮和标题 |
| 输入框 | 28-33 | 备忘内容输入 |
| 添加按钮 | 35-45 | 添加备忘录功能 |
| 列表标题 | 47-51 | 备忘录列表标题 |
| 备忘录列表 | 53-69 | 展示和删除备忘录 |
八、组件对比分析
8.1 TextInput与其他输入组件对比
| 组件 | 用途 | 特点 | 适用场景 |
|---|
| TextInput | 单行文本输入 | 简单易用,适合短文本 | 用户名、搜索、备忘内容 |
| TextArea | 多行文本输入 | 支持换行,适合长文本 | 评论、描述、文章内容 |
| Search | 搜索输入 | 自带搜索图标和清除按钮 | 搜索功能 |
| PasswordInput | 密码输入 | 自动隐藏输入内容 | 密码、敏感信息 |
8.2 Button与其他交互组件对比
| 组件 | 用途 | 特点 | 适用场景 |
|---|
| Button | 通用按钮 | 样式丰富,事件简单 | 提交、确认、导航 |
| Toggle | 开关切换 | 二态切换,状态明确 | 设置开关、功能启用 |
| Checkbox | 多选框 | 支持多选,状态独立 | 多选列表、选项组 |
| Radio | 单选按钮 | 互斥选择,状态关联 | 单选列表、选项组 |
| Slider | 滑动条 | 连续值选择 | 音量、亮度调节 |
8.3 List与其他容器组件对比
| 组件 | 用途 | 特点 | 适用场景 |
|---|
| List | 列表容器 | 高性能滚动,自动回收 | 长列表、数据展示 |
| Column | 垂直容器 | 简单垂直排列 | 页面布局、固定内容 |
| Grid | 网格容器 | 规则网格排列 | 图片墙、应用列表 |
| Scroll | 滚动容器 | 通用滚动容器 | 长内容滚动 |
| WaterFlow | 瀑布流 | 不规则高度排列 | 图片瀑布流 |
九、最佳实践
9.1 状态管理最佳实践
addMemo(content: string) {
if (content.trim() !== '') {
this.memos_1 = [...this.memos_1, content.trim()];
this.inputText_1 = '';
}
}
removeMemo(index: number) {
if (index >= 0 && index < this.memos_1.length) {
this.memos_1 = this.memos_1.filter((_, i) => i !== index);
}
}
validateInput(text: string): boolean {
return text !== null && text.trim() !== '' && text.length <= 100;
}
9.2 性能优化最佳实践
ForEach(
this.memos_1,
(item_1: string, index_1: number) => {
ListItem() {
}
},
(item_1: string, index_1: number) => {
return 'memo_' + index_1 + '_' + item_1.length;
}
)
LazyForEach(
this.memoDataSource,
(item: MemoItem) => {
ListItem() {
}
},
(item: MemoItem) => item.id
)
9.3 用户体验最佳实践
Button('添加')
.onClick(() => {
if (this.inputText_1.trim() === '') {
return;
}
if (this.inputText_1.length > 100) {
return;
}
this.memos_1 = [...this.memos_1, this.inputText_1.trim()];
this.inputText_1 = '';
})
Button('删除')
.onClick(() => {
AlertDialog.show({
title: '确认删除',
message: '确定要删除这条备忘录吗?',
primaryButton: {
value: '取消',
action: () => {}
},
secondaryButton: {
value: '删除',
action: () => {
this.memos_1 = this.memos_1.filter((_, i) => i !== index_1);
}
}
});
})
9.4 代码组织最佳实践
const STYLES = {
colors: {
primary: '#0A59F7',
danger: '#FF3B30',
background: '#FFFFFF',
navBackground: '#F1F3F5'
},
sizes: {
titleSize: 20,
subtitleSize: 16,
bodySize: 14,
smallSize: 12
},
spacing: {
small: 8,
medium: 12,
large: 20,
xlarge: 24
}
};
@Component
struct MemoApp {
@State inputText_1: string = '';
@State memos_1: string[] = [];
addMemo() {
if (this.validateInput(this.inputText_1)) {
this.memos_1 = [...this.memos_1, this.inputText_1.trim()];
this.inputText_1 = '';
}
}
removeMemo(index: number) {
this.memos_1 = this.memos_1.filter((_, i) => i !== index);
}
validateInput(text: string): boolean {
return text !== null && text.trim() !== '' && text.length <= 100;
}
build() {
}
}
十、扩展功能设计
10.1 数据持久化
import preferences from '@ohos.data.preferences';
async saveMemos() {
try {
const context = getContext(this);
const pref = await preferences.getPreferences(context, 'memo_store');
await pref.put('memos', JSON.stringify(this.memos_1));
await pref.flush();
} catch (error) {
console.error('保存失败:' + error);
}
}
async loadMemos() {
try {
const context = getContext(this);
const pref = await preferences.getPreferences(context, 'memo_store');
const data = await pref.get('memos', '[]');
this.memos_1 = JSON.parse(data as string);
} catch (error) {
console.error('加载失败:' + error);
}
}
10.2 分类管理功能
class MemoItem {
id: string = '';
content: string = '';
category: string = 'default';
createTime: number = 0;
isCompleted: boolean = false;
}
@State categories: string[] = ['工作', '生活', '学习', '其他'];
@State currentCategory: string = 'all';
get filteredMemos(): MemoItem[] {
if (this.currentCategory === 'all') {
return this.memos_1;
}
return this.memos_1.filter(item => item.category === this.currentCategory);
}
10.3 搜索功能
@State searchText: string = '';
TextInput({ placeholder: '搜索备忘录...' })
.width('90%')
.height(40)
.margin({ top: 10 })
.onChange((value: string) => {
this.searchText = value;
})
get searchedMemos(): string[] {
if (this.searchText === '') {
return this.memos_1;
}
return this.memos_1.filter(item =>
item.toLowerCase().includes(this.searchText.toLowerCase())
);
}
10.4 优先级功能
enum Priority {
LOW = 'low',
MEDIUM = 'medium',
HIGH = 'high'
}
class PriorityMemo {
id: string = '';
content: string = '';
priority: Priority = Priority.MEDIUM;
createTime: number = 0;
}
getPriorityColor(priority: Priority): string {
const colors = {
[Priority.LOW]: '#4CAF50',
[Priority.MEDIUM]: '#FF9800',
[Priority.HIGH]: '#F44336'
};
return colors[priority];
}
10.5 完成状态功能
class TodoItem {
id: string = '';
content: string = '';
isCompleted: boolean = false;
createTime: number = 0;
}
toggleComplete(id: string) {
this.memos_1 = this.memos_1.map(item => {
if (item.id === id) {
return { ...item, isCompleted: !item.isCompleted };
}
return item;
});
}
Text(item.content)
.fontColor(item.isCompleted ? '#999999' : '#333333')
.decoration({ type: item.isCompleted ? TextDecorationType.LineThrough : TextDecorationType.None })
十一、性能优化策略
11.1 列表渲染优化
class MemoDataSource implements IDataSource {
private memos: string[] = [];
private listeners: DataChangeListener[] = [];
totalCount(): number {
return this.memos.length;
}
getData(index: number): string {
return this.memos[index];
}
registerDataChangeListener(listener: DataChangeListener): void {
this.listeners.push(listener);
}
unregisterDataChangeListener(listener: DataChangeListener): void {
this.listeners = this.listeners.filter(l => l !== listener);
}
}
List() {
LazyForEach(
this.memoDataSource,
(item: string, index: number) => {
ListItem() {
}
},
(item: string, index: number) => {
return 'memo_' + index;
}
)
}
11.2 状态更新优化
addMultipleMemos(contents: string[]) {
const newMemos = contents.filter(c => c.trim() !== '');
this.memos_1 = [...this.memos_1, ...newMemos];
}
addMultipleMemosSlow(contents: string[]) {
contents.forEach(c => {
if (c.trim() !== '') {
this.memos_1 = [...this.memos_1, c];
}
});
}
11.3 组件复用优化
@Component
struct MemoItem {
@Prop content: string = '';
@Prop index: number = 0;
onDelete: (index: number) => void = () => {};
build() {
Row() {
Text(this.content)
.fontSize(14)
.layoutWeight(1)
Button('删除')
.width(60)
.height(32)
.fontSize(12)
.backgroundColor('#FF3B30')
.onClick(() => {
this.onDelete(this.index);
})
}
.padding(12)
.width('100%')
}
}
List() {
ForEach(this.memos_1, (item: string, index: number) => {
ListItem() {
MemoItem({
content: item,
index: index,
onDelete: (i: number) => {
this.memos_1 = this.memos_1.filter((_, idx) => idx !== i);
}
})
}
})
}
十二、总结
随手记备忘录小应用是一个典型的HarmonyOS ArkUI入门项目,通过这个项目我们学习了以下核心知识点:
12.1 技术要点总结
| 技术点 | 学习内容 | 实践应用 |
|---|
| 状态管理 | @State装饰器的使用 | 管理输入内容和备忘录列表 |
| 组件使用 | TextInput、Button、List、ForEach | 构建完整的用户界面 |
| 布局技术 | Column、Row、layoutWeight | 实现响应式布局 |
| 事件处理 | onChange、onClick | 处理用户交互 |
| 数组操作 | concat、filter | 实现添加和删除功能 |
12.2 开发流程总结
需求分析 → 界面设计 → 组件选择 → 状态设计 → 事件处理 → 样式定制 → 测试优化
12.3 最佳实践总结
- 状态管理:使用不可变数据更新数组,确保UI正确刷新
- 性能优化:为ForEach提供key生成函数,大数据使用LazyForEach
- 代码组织:提取样式常量,封装业务逻辑方法
- 用户体验:添加输入验证、删除确认等交互优化
12.4 扩展方向
- 数据持久化:使用Preferences存储备忘录数据
- 分类管理:支持按类别分组备忘录
- 搜索功能:支持关键字搜索备忘录
- 优先级设置:支持标记重要程度
- 完成状态:支持标记已完成事项
- 提醒功能:支持定时提醒通知
通过这个项目的学习,开发者可以掌握HarmonyOS ArkUI的基础开发技能,为开发更复杂的应用打下坚实基础。本应用虽然功能简单,但涵盖了状态管理、列表渲染、事件处理、样式定制等核心知识点,是学习ArkUI开发的优秀实践案例。