【共创季稿事节】HarmonyOS动态任务列表开发实战
2026/6/13 9:03:06 网站建设 项目流程

HarmonyOS 动态任务列表应用开发实战

API Version 24 | ArkUI 声明式 UI | ArkTS

一、前言

随着 HarmonyOS Next 的推进,越来越多的开发者关注纯血鸿蒙应用开发。ArkTS 融合了 TypeScript 的类型安全与声明式 UI 的开发效率,为移动端开发带来全新体验。

本文以一个完整的“动态任务列表”应用为案例,从项目结构、页面布局、状态管理到交互逻辑,带您掌握 HarmonyOS 应用开发的核心技术。

二、应用功能概览

本应用是一个功能完整的待办事项管理工具,包含以下特性:

  1. 新建任务— 输入标题、可选副标题,选择优先级(高/中/低)
  2. 任务列表展示— 标题、副标题、优先级彩色标签
  3. 完成状态切换— 点击任务项切换,已完成显示删除线和绿色对勾
  4. 左滑删除— 向左滑动露出红色删除按钮
  5. 清除已完成— 一键清除所有已完成任务
  6. 重置示例— 恢复三个预设示例任务
  7. 实时统计— 顶部显示任务总数

三、项目结构

使用 DevEco Studio 创建 Empty Ability 模板项目(API 24),目录结构如下:

app6124/ ├── AppScope/app.json5 # 应用级配置 ├── entry/src/main/ │ ├── ets/ │ │ ├── entryability/ # Ability 生命周期 │ │ └── pages/Index.ets # 主页面 │ ├── module.json5 # 模块配置 │ └── resources/base/media/ # 图标资源(SVG) ├── build-profile.json5 # 项目级构建 └── hvigor/ # Hvigor 构建配置

四、核心技术实现

4.1 数据模型层

通过枚举和自定义类定义任务的数据结构:

enumPriority{HIGH='HIGH',MEDIUM='MEDIUM',LOW='LOW'}classTaskItem{title:string;subtitle:string;priority:Priority;completed:boolean;constructor(title:string,subtitle:string,priority:Priority,completed:boolean){this.title=title;this.subtitle=subtitle;this.priority=priority;this.completed=completed;}}

使用enum+class的组合,配合@State装饰器实现响应式追踪。当任务对象的属性变化时,ArkUI 会自动侦测并刷新 UI。

4.2 主页面结构

页面使用@Entry@Component装饰器标记,这是 ArkTS 声明式 UI 的核心模式:

@Entry@Componentstruct Index{@Statetasks:TaskItem[]=[];@StatenewTaskTitle:string='';@StatenewTaskSubtitle:string='';@StatenewTaskPriority:Priority=Priority.HIGH;@StatepriorityPickerShow:boolean=false;aboutToAppear():void{this.resetSampleTasks();}// ... 方法}
装饰器作用
@Entry标记为页面入口,可作为路由目标
@Component声明该结构体是 UI 组件
@State标记为响应式状态,修改后自动触发 UI 刷新

4.3 顶层布局

采用Column纵向布局,背景色为浅灰色(#F2F2F7),模拟分组列表效果:

build(){Column(){// 1. 标题栏// 2. 新建任务输入区// 3. 操作按钮// 4. 任务列表// 5. 底部提示}.width('100%').height('100%').backgroundColor('#F2F2F7')}

4.4 标题栏

使用Row水平布局,左侧应用名称,右侧任务总数,中间用Blank()撑满:

Row(){Text('动态任务列表').fontSize(22).fontWeight(FontWeight.Bold).fontColor('#1C1C1E')Blank()Text(`${this.tasks.length}`).fontSize(14).fontColor('#8E8E93')}.width('100%').padding({left:16,right:16,top:12,bottom:8})

Blank组件类似于 Flexbox 的flex-grow: 1,自动占据剩余空间实现两端对齐。

4.5 新建任务输入区

输入区包含三部分:标题输入框、副标题输入框、优先级选择器 + 添加按钮行。

TextInput组件通过@State双向绑定数据:

TextInput({placeholder:'输入新任务...',text:this.newTaskTitle}).placeholderColor('#C7C7CC').fontSize(16).height(44).padding({left:12}).onChange((value:string)=>{this.newTaskTitle=value;})

优先级选择器设计为弹出式下拉菜单,使用Radio单选组件:

if(this.priorityPickerShow){Column(){ForEach([Priority.HIGH,Priority.MEDIUM,Priority.LOW],(p:Priority)=>{Row(){Radio({value:this.getPriorityText(p),group:'priority'}).checked(this.newTaskPriority===p).onChange(()=>{this.setPriority(p);})Text(this.getPriorityText(p)).fontSize(15)}.onClick(()=>{this.setPriority(p);})})}// ...样式}

这里使用条件渲染if直接写在 UI 描述中)控制下拉菜单显示隐藏,比visible属性更直观高效。

4.6 添加任务逻辑

addTask():void{consttitle=this.newTaskTitle.trim();if(!title)return;this.tasks.push(newTaskItem(title,this.newTaskSubtitle.trim(),this.newTaskPriority,false));this.newTaskTitle='';this.newTaskSubtitle='';this.newTaskPriority=Priority.HIGH;}

由于tasks@State装饰,push操作自动触发列表重新渲染。ArkTS 对数组的响应式追踪支持pushsplicefilter等常见操作。

4.7 操作按钮区

两个按钮并排,分别使用红色和绿色背景,内部包含图标 + 文字:

Button(){Row(){Image($r('app.media.ic_checkmark')).width(16).height(16).fillColor('#FFFFFF')Text('清除已完成').fontSize(14).fontColor('#FFFFFF').margin({left:4})}}.height(36).backgroundColor('#FF3B30').borderRadius(18).padding({left:14,right:14}).onClick(()=>{this.clearCompleted();})

使用带子组件的 Button——Button()不传 label,内部用Row+Image+Text自定义内容。这与Button('文字')的单标签模式是两种不同用法。

4.8 任务列表

使用List+ListItem+ForEach组合:

List({space:0}){ForEach(this.tasks,(task:TaskItem,index:number)=>{ListItem(){// 任务卡片 UI}.onClick(()=>{this.toggleTaskCompletion(index);}).swipeAction({end:():void=>this.deleteSwipeAction(index)})})}.width('100%').layoutWeight(1).divider({strokeWidth:'0.5px',color:'#E5E5EA',startMargin:52,endMargin:0})
  • ForEach— 遍历数组,增量更新 DOM
  • swipeAction— 左滑操作,使用@Builder构建面板
  • divider— 列表分隔线,支持缩进控制
  • .layoutWeight(1)— 占满剩余空间

4.9 左滑删除

swipeActionend属性接收构建函数。ArkTS 不支持Function.bind,使用lambda 闭包传参:

@BuilderdeleteSwipeAction(index:number){Button(){Image($r('app.media.ic_delete')).width(24).height(24).fillColor('#FFFFFF')}.width(68).height('100%').backgroundColor('#FF3B30').borderRadius(0).onClick(()=>{this.deleteTask(index);})}

@Builder装饰器可以将一段 UI 描述封装为可复用构建函数,内可直接编写声明式 UI 代码。

4.10 条件样式渲染

根据完成状态动态切换样式:

Image(task.completed?$r('app.media.ic_checkmark_circle'):$r('app.media.ic_circle')).fillColor(task.completed?'#34C759':'#C7C7CC')Text(task.title).fontColor(task.completed?'#8E8E93':'#1C1C1E').decoration({type:task.completed?TextDecorationType.LineThrough:TextDecorationType.None})

使用三元运算符动态控制样式属性,无需分支代码,非常简洁。

4.11 核心方法

toggleTaskCompletion(index:number):void{if(index>=0&&index<this.tasks.length){this.tasks[index].completed=!this.tasks[index].completed;}}deleteTask(index:number):void{if(index>=0&&index<this.tasks.length){this.tasks.splice(index,1);}}clearCompleted():void{this.tasks=this.tasks.filter(task=>!task.completed);}resetSampleTasks():void{this.tasks=[newTaskItem('学习 @State 装饰器','掌握声明式响应式数据绑定',Priority.HIGH,true),newTaskItem('探索 Grid 布局','了解网格布局的参数配置',Priority.LOW,false),newTaskItem('完成第一篇笔记','将学到的知识整理成文档',Priority.MEDIUM,false),];}

修改@State数组后,UI 自动响应式更新。

五、资源文件管理

resources/base/media/下存放 6 个 SVG 图标:

文件用途
ic_arrow_down.svg优先级下拉箭头
ic_checkmark.svg对勾图标
ic_checkmark_circle.svg实心圆圈对勾(已完成)
ic_circle.svg空心圆圈(未完成)
ic_refresh.svg刷新图标
ic_delete.svg删除图标

SVG 图标的优势是可通过.fillColor()动态修改颜色,无需为每种颜色准备独立图片。

六、构建与部署

6.1 构建

终端执行:

hvigorw assembleHap

流程:PreBuild → CreateModuleInfo → MergeProfile → ProcessResource →CompileArkTS→ PackageHap → SignHap → 完成。

6.2 常见问题

问题 1:Button 标签冲突

Error: The Button component with a label parameter can not have any child.

要么用Button('文字')不带花括号,要么用Button() { Text('文字') },二者选一。

问题 2:Function.bind 不支持

Error: 'Function.bind' is not supported (arkts-no-func-bind)

ArkTS 禁用了bind,改用 lambda:() => this.myMethod(arg)

问题 3:属性命名冲突

Warning: ... cannot have name as 'activeCount'.

某些名称与系统属性冲突,换名即可(如incompleteCount)。

问题 4:运行时闪退
检查module.json5pages是否指向正确的$profile:main_pages,以及main_pages.json的页面路径是否匹配。

七、ArkTS 开发最佳实践

7.1 声明式 UI 思维

ArkTS 采用声明式范式,与传统命令式 UI 本质不同:

传统命令式ArkTS 声明式
手动 findViewById直接编写 UI 描述
手动 setText/setColorUI 自动随状态变化
复杂的 Diff 刷新细粒度响应式追踪

写作 UI 时思考"当前状态下 UI 应该什么样",而非"怎么修改控件"。

7.2 响应式状态体系

装饰器场景
@State组件内自有状态
@Prop父→子单向传递
@Link父子双向同步
@Provide/@Consume跨层级通信
@Observed/@ObjectLink深层对象观测

7.3 组件化拆分建议

应用功能增长时拆分为子组件:

Index → TaskHeader + TaskInput(含 PriorityPicker) → TaskActions + TaskList(含 TaskCard)+ TaskFooter

子组件通过@Prop/@Link通信,保持代码清晰可维护。

7.4 生命周期

钩子时机
aboutToAppear组件创建前,初始化数据
onPageShow页面显示
onPageHide页面隐藏
aboutToDisappear组件销毁前,清理资源

八、扩展方向

当前应用功能完整,还可扩展:

  1. 数据持久化— 使用@ohos.data.preferences@ohos.data.relationalStore保存任务
  2. 任务编辑— 长按弹出对话框修改标题/副标题/优先级
  3. 搜索筛选— 按关键词搜索、按优先级筛选
  4. 拖拽排序— 使用ListItemdragEnabled属性
  5. 时间提醒— 结合@ohos.backgroundTaskManager发送本地通知
  6. 深色模式— 监听configurationChange切换主题

九、总结

本文从零构建了一个完整的 HarmonyOS 动态任务列表应用,涵盖了:

  1. ArkTS 基础— 枚举、类、装饰器、泛型
  2. ArkUI 核心组件— Column、Row、Text、TextInput、Button、List、Image、Radio、Stack
  3. 声明式 UI 语法— 条件渲染、循环渲染、@Builder
  4. 响应式状态— @State 与数组响应式追踪
  5. 事件处理— onClick、onChange、swipeAction
  6. 资源管理— SVG 图标引用与动态着色
  7. 构建部署— Hvigor 流程与问题排查

通过这个项目,您已掌握 HarmonyOS 应用开发的核心流程。声明式 UI 需要一些时间适应,但上手后会发现代码更简洁、维护成本更低。

项目完整代码位于entry/src/main/ets/pages/Index.ets,SVG 图标位于resources/base/media/。使用 DevEco Studio 打开即可运行体验。

本文发布于 HarmonyOS Next API 24,所有代码均已通过hvigorw assembleHap构建验证,零错误零警告。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询