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

鸿蒙原生应用从0到1:项目搭建与首页开发实战

鸿蒙原生应用从0到1:项目搭建与首页开发实战

本系列文章将带大家从零开发一个完整的鸿蒙原生应用——「生活助手」,涵盖项目搭建、页面开发、状态管理、数据交互等核心实战内容。


一、写在前面

鸿蒙生态发展至今,原生应用开发已经不再是"要不要学"的问题,而是"什么时候开始学"的问题。作为一名移动端开发者,我决定用 ArkTS + Stage 模型开发一个完整的「生活助手」App,把我的学习和实战过程记录下来,希望对同样在学习的你有所帮助。

本文是系列第一篇,重点讲解项目搭建、工程结构设计、以及首页的开发实现


二、项目概况

「生活助手」是一个集待办管理、记账理财、备忘录、心情日记、个人中心于一体的日常管理工具,涵盖了一个完整 App 开发中的核心场景:

功能模块核心能力技术亮点
首页仪表盘每日一言、统计概览、快捷入口、动态流Scroll + 组合 Builder
待办管理分类筛选、优先级标记、添加/删除/切换完成状态管理 + 过滤逻辑
记账本收支汇总、分类统计、记录管理数据聚合计算
备忘录分类筛选、搜索、详情查看、编辑搜索逻辑 + 多视图切换
心情日记日历视图、情绪记录、月度统计日历算法 + 数据可视化

三、项目搭建 —— 从 DevEco Studio 开始

3.1 创建项目

打开 DevEco Studio,选择File → New → Create Project

  • 模板选择:Empty Ability(Stage 模型)
  • 兼容版本:API 9+(我选择 API 23,对应新版 SDK)
  • 包名com.example.myapplication
  • 项目位置:自行选择

创建完成后,你会看到如下工程结构:

MyApplication/ ├── AppScope/ # 全局应用配置 │ ├── app.json5 # 应用级配置 │ └── resources/ # 全局资源 ├── entry/ # 应用主模块 │ ├── src/ │ │ ├── main/ │ │ │ ├── ets/ # 代码目录 │ │ │ │ ├── entryability/ # Ability 生命周期 │ │ │ │ └── pages/ # 页面文件 │ │ │ ├── resources/ # 资源文件 │ │ │ └── module.json5 # 模块配置 │ ├── build-profile.json5 # 构建配置 │ └── oh-package.json5 # 包依赖 ├── hvigor/ # 构建工具配置 ├── build-profile.json5 # 全局构建配置 └── oh-package.json5 # 全局包依赖

3.2 重要配置文件解读

AppScope/app.json5 —— 应用级配置
{"app":{"bundleName":"com.example.myapplication","vendor":"example","versionCode":1000000,"versionName":"1.0.0","icon":"$media:layered_image","label":"$string:app_name"}}

这里配置了应用的包名、版本号、图标和显示名称bundleName是应用的唯一标识,一旦发布不可修改。

entry/src/main/module.json5 —— 模块配置
{"module":{"name":"entry","type":"entry","deviceTypes":["phone"],"pages":"$profile:main_pages","abilities":[{"name":"EntryAbility","srcEntry":"./ets/entryability/EntryAbility.ets","exported":true,"skills":[{"entities":["entity.system.home"],"actions":["ohos.want.action.home"]}]}]}}

关键点:

  • deviceTypes:声明支持的设备类型,这里仅支持 phone
  • pages:引用$profile:main_pages,对应resources/base/profile/main_pages.json
  • skills:声明该 Ability 可以响应桌面启动意图
main_pages.json —— 页面路由注册
{"src":["pages/Index","pages/TodoPage","pages/FinancePage","pages/NotePage","pages/MoodPage","pages/ProfilePage"]}

所有页面都必须在这里注册,否则无法通过router.pushUrl()跳转。


四、资源体系 —— 颜色、字号、字符串

鸿蒙应用推荐使用资源引用($r)的方式来管理 UI 属性,而不是写死常量值。这样做的好处是:

  1. 支持深色模式自动切换(同一资源名,不同值)
  2. 支持多语言适配
  3. 修改一处,全局生效

4.1 颜色资源

// resources/base/element/color.json{"color":[{"name":"primary","value":"#5B7FFF"},{"name":"primary_light","value":"#E8ECFF"},{"name":"text_primary","value":"#1A1A2E"},{"name":"text_secondary","value":"#6B7280"},{"name":"bg_primary","value":"#F5F7FA"},{"name":"bg_card","value":"#FFFFFF"},{"name":"divider","value":"#E5E7EB"},{"name":"shadow","value":"#1A000000"}]}

我还为深色模式单独配置了dark/element/color.json,应用会自动根据系统主题切换。

4.2 字号资源

// resources/base/element/float.json{"float":[{"name":"title_font_size","value":"24fp"},{"name":"subtitle_font_size","value":"18fp"},{"name":"body_font_size","value":"16fp"},{"name":"small_font_size","value":"14fp"},{"name":"tiny_font_size","value":"12fp"},{"name":"card_radius","value":"16vp"},{"name":"button_radius","value":"12vp"}]}

注意fp是鸿蒙特有的字体单位(类似 Android 的 sp),会跟随系统字体缩放;vp是虚拟像素单位(类似 dp)。

在代码中这样引用:

Text('标题').fontSize($r('app.float.title_font_size')).fontColor($r('app.color.text_primary'))

五、EntryAbility —— 应用入口分析

// entryability/EntryAbility.etsexportdefaultclassEntryAbilityextendsUIAbility{onCreate(want:Want,launchParam:AbilityConstant.LaunchParam):void{this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);}onWindowStageCreate(windowStage:window.WindowStage):void{windowStage.loadContent('pages/Index',(err)=>{if(err.code){hilog.error(DOMAIN,'testTag','Failed to load content: %{public}s',JSON.stringify(err));}});}}

核心逻辑:

  • onCreate:设置颜色模式为跟随系统(NOT_SET)
  • onWindowStageCreate:加载首页pages/Index
  • 使用hilog日志系统记录关键生命周期事件

六、首页开发 —— 生活助手仪表盘

首页是整个 App 的门面,我设计了一个信息型仪表盘,包含以下区域:

┌─────────────────────────────┐ │ 生活助手 2025年1月15日 │ ← 顶部标题栏 │ 👤│ ← 点击跳转个人中心 ├─────────────────────────────┤ │ 📖 每日一言 [换一句]│ ← 可切换的名人名言 │ "生活不止眼前的苟且..." │ │ —— 高晓松 │ ├─────────────────────────────┤ │ 📋 今日待办 │ 💰 本月支出 │ ← 2×2 统计卡片 │ 5项 │ 3,280元 │ │ 📝 备忘录 │ 🔥 连续打卡 │ │ 12篇 │ 7天 │ ├─────────────────────────────┤ │ ➕新增待办 💳记一笔 │ ← 快捷操作栏 │ ✏️写笔记 😊记心情 │ ├─────────────────────────────┤ │ 最近动态 │ ← 活动流 │ 📋 完成项目方案 10:30 │ │ 💰 午餐支出 12:00 │ │ 📝 读书笔记 14:30 │ └─────────────────────────────┘

6.1 数据模型定义

ArkTS 中定义接口统一使用interface

interfaceDailyQuote{text:string;author:string;}interfaceStatItem{title:string;value:string;unit:string;color:string;icon:string;}interfaceQuickAction{name:string;icon:string;page:string;color:string;}interfaceActivityItem{title:string;desc:string;time:string;type:string;// 'todo' | 'finance' | 'note' | 'mood'}

6.2 状态与数据初始化

@Componentstruct Index{@StatecurrentQuoteIndex:number=0;@StatecurrentDate:string='';@StateuserName:string='用户';privatequotes:DailyQuote[]=[{text:'生活不止眼前的苟且,还有诗和远方',author:'高晓松'},{text:'千里之行,始于足下',author:'老子'},// ...];aboutToAppear():void{this.updateDate();}updateDate():void{constnow=newDate();constweekDays:string[]=['日','一','二','三','四','五','六'];this.currentDate=`${now.getFullYear()}${now.getMonth()+1}${now.getDate()}日 星期${weekDays[now.getDay()]}`;}}

这里有一个细节:updateDate()aboutToAppear()中调用,确保进入页面时日期是最新的。aboutToAppear是 ArkTS 的生命周期钩子,类似 Vue 的onMounted

6.3 每日一言 —— 交互卡片

Column(){Row(){Text('📖 每日一言')Blank()Text('换一句').fontColor($r('app.color.primary')).onClick(()=>{this.currentQuoteIndex=(this.currentQuoteIndex+1)%this.quotes.length;})}Text(this.quotes[this.currentQuoteIndex].text).lineHeight(24)Text(`——${this.quotes[this.currentQuoteIndex].author}`)}

通过currentQuoteIndex状态 + 取模运算实现循环切换。点击"换一句"会触发 UI 重新渲染,因为@State装饰器标记了该变量。

6.4 统计卡片 —— @Builder 复用

为了避免重复写相同的卡片布局,我使用了@Builder装饰器:

@BuilderstatCard(item:StatItem):void{Column(){Row(){Text(item.icon)Text(item.value).fontColor(item.color)}Row(){Text(item.title)Text(item.unit)}}}

在 build 方法中直接调用:

Row(){ForEach(this.stats.slice(0,2),(item:StatItem)=>{this.statCard(item)},(item:StatItem)=>item.title)}

ForEach的第三个参数是键生成函数,用于优化列表渲染性能,类似 React 的key

6.5 路由跳转

// 导航到个人中心.onClick(()=>{router.pushUrl({url:'pages/ProfilePage'});})// 快捷操作.onClick(()=>{router.pushUrl({url:action.page});})

注意:路由的url不需要.ets后缀,且路径相对于pages目录。需要在main_pages.json中注册。

6.6 活动流 —— 动态类型映射

getActivityIcon(type:string):string{consticons:Record<string,string>={'todo':'📋','finance':'💰','note':'📝','mood':'😊'};returnicons[type]||'📌';}getActivityColor(type:string):ResourceColor{constcolors:Record<string,string>={'todo':'#E8ECFF','finance':'#FFF3E0','note':'#E8F5E9','mood':'#F3E5F5'};returncolors[type]||'#F5F5F5';}

这里使用了Record<string, string>类型来定义映射表,避免使用switch-case长篇代码,非常简洁。


七、技术总结

本篇核心知识点

知识点说明
Stage 模型鸿蒙推荐的 Ability 架构,模块化清晰
main_pages.json 路由注册所有页面必须在此注册
$r 资源引用颜色/字号/字符串统一管理
@Component + @State声明式 UI 与状态驱动
@BuilderUI 组件复用
ForEach列表渲染与 key 优化
router.pushUrl跨页面导航

避坑指南

  1. 路由路径不加.ets后缀router.pushUrl({ url: 'pages/TodoPage' })而非TodoPage.ets
  2. 对象字面量必须显式声明类型:ArkTS 严格模式下不允许推断对象类型,所有数组元素必须标注接口
  3. @State只监听一层深度的变化:数组内元素的属性变化不会被追踪,需要用this.todos = [...this.todos]触发刷新
  4. 资源引用用$r('app.xxx.xxx'):不要硬编码颜色/字号值

八、下篇预告

下一篇中,我们将深入开发**「待办事项」页面**,涵盖:

  • 分类标签筛选的实现
  • 待办 CRUD(增删改查)完整流程
  • 状态管理的最佳实践
  • 弹窗对话框的设计与交互

欢迎持续关注,一起掌握鸿蒙原生应用开发!

http://www.gsyq.cn/news/1526836.html

相关文章:

  • GSV5800@ACP#Serdes 高速延长芯片,物理 AI 分布式显示的传输骨干
  • 2026年西北地区消防水箱与生活水箱供应商综合评估:从技术实力到项目案例的全景分析 - 优质品牌商家
  • 2026年CPE硫化剂厂家选型参考:技术参数、应用场景与主流供应商分析 - 优质品牌商家
  • 如何让老款Mac运行最新macOS?OpenCore Legacy Patcher完整指南
  • GY001-WiFiBLE+4G转CAN总线或RS485中高速通信 - 4G通信CAN数据发送到UDP, GPS上传数据, 4G转CAN总线的1毫秒一帧通信测试,实际做到了微秒级速率
  • 2026年镀锌铁皮架空保温钢管厂家怎么选?四川、西藏、贵州市场深度分析与真实案例参考 - 优质品牌商家
  • trace.moe:如何用AI瞬间定位任意动漫场景
  • 企业加密软件排行榜,6款企业透明加密软件分享,亲测推荐
  • 计算机Java毕设实战-基于 SpringBoot 框架的高校校园信息交互系统的设计与实现 面向师生的校园信息共享服务系统【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 2026年6月专业的石家庄三角钢琴搬运公司口碑推荐:立式钢琴、三角钢琴、自动演奏钢琴搬运选择指南 - 海棠依旧大
  • 制冷高效商用冷柜批发厂家排行:全场景选型参考 - 互联网科技品牌测评
  • 2026年溶液调湿空调厂家电话汇总:技术路线与工程案例深度评测 - 优质品牌商家
  • 2026年佛山专利申请与无效律师推荐指南:从家电到灯饰全覆盖 - 本地品牌推荐
  • 3个核心策略:将Obsidian笔记库转化为智能数据系统
  • 2026 深圳管道疏通与异味治理机构精选 5 家 马桶 / 厨卫下水 / 地漏除臭服务参考 - 宅安选房屋修缮
  • 2026 上饶空调维修 线路老化排查 家电上门抢修 口碑机构推荐 - 金修达家庭维修
  • 2026成都店铺装修口碑推荐:商业空间设计施工机构综合评估 - 优质品牌商家
  • 2026年6月正规的河南脱粉机厂家有哪些推荐,细粉分级机/干式分级机/干式风选机厂家选择指南 - 海棠依旧大
  • 生成器generator:yield、生成器表达式、内存节省原理
  • 3分钟搞定浏览器资源嗅探:猫抓Cat-Catch让你的在线资源触手可及
  • 认准正规老字号!古籍拓片变现如何从源头杜绝仿冒套路、安心交易 - 深鉴新闻
  • 2026年6月市面上单级反渗透纯水设备厂家哪家靠谱推荐:工业净水系统、反渗透设备、纯水机、去离子水设备公司选择指南 - 海棠依旧大
  • OmenSuperHub:开源免费的惠普游戏本终极性能控制工具
  • 深耕东莞环保产业|武科环保打造研发 - 设计 - 施工 - 运维全链条一体化绿色治理标杆 - 广东科技观察
  • MPC8533E勘误文档深度解析:寄存器级编程避坑与实战指南
  • 沧州空调应急维修、线路故障排查,家电维修甄选指南2026年6月最新 - 金修达家庭维修
  • X1nput终极指南:一键解锁Xbox手柄完整震动体验
  • 2026排插什么牌子性价比高 实用选购参考 - 品牌排行榜
  • 2026成都林德伯格镜框授权指南:6家靠谱服务商横向对比与选购建议 - 优质品牌商家
  • 程序员职业规划:大模型时代如何重新设计路线:从踩坑到可复用方案