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

鸿蒙音乐播放器实战01|从零搭建项目骨架:导航架构与广告启动页完整实现

大家好,欢迎来到鸿蒙音乐播放器实战系列的第一篇。

这个系列我们会从零开始,手把手带大家做一个连贯完整、可迭代商用的鸿蒙原生音乐播放器,全程不做单页演示、不写废弃占位代码。从项目骨架、页面路由、导航架构,到UI布局、播放能力、后台保活,循序渐进完成完整项目开发。

作为开篇第一篇,我们核心完成项目底层骨架搭建:统一页面创建规范、配置全局路由体系、搭建全局导航栈、实现商用全屏广告启动页,同时完整搭建主页基础骨架,保证APP启动、跳转全流程闭环可运行,为后续所有功能迭代打底。

本篇学习目标

  • 理解鸿蒙Stage模型的项目结构,理清页面、路由、入口函数的对应关系

  • 掌握router_map.json路由表配置规则,独立完成多页面路由注册

  • 理解 Navigation + NavPathStack 导航原理,搭建全局统一导航架构

  • 分清pushPathByNamereplacePathByName的业务使用场景

  • 实现全屏沉浸式广告启动页(3秒自动跳转+手动跳过)

  • 掌握鸿蒙安全区适配、无报错页面创建、路由注册全套规范

  • 解决导入报错、路由找不到、页面空白、返回退回广告页等常见问题

一、先理清:我们的项目整体结构(连贯开发)

本项目为完整连贯工程,所有页面逐层迭代开发,无临时占位、无废弃代码,核心四大页面结构固定:

  1. Index 入口页:APP根容器,仅承载全局导航栈,不展示业务UI

  2. Start 广告启动页:APP首个展示页,负责启动过渡、自动/手动跳转主页

  3. Layout 布局主页:APP核心主页,后续迭代底部Tab、多页面切换、首页UI

  4. Play 播放页:后续开发,歌曲播放、动画、播控、播放列表页面

全局统一采用Navigation + NavPathStack官方导航方案,所有页面跳转、栈管理统一受控,保证项目架构统一规范。

二、第一步:路由配置,给每个页面办「身份证」

鸿蒙Stage模型硬性规则:所有页面必须提前在路由表注册,否则无法跳转、系统识别不到页面。

1. 声明路由表文件

打开项目配置文件src/main/module.json5,在 module 节点下新增路由表声明,告诉系统路由配置文件位置:

{ "module": { // ... 原有默认配置 "routerMap": "$profile:router_map", // ... 原有默认配置 . . .

作用:绑定resources/base/profile/router_map.json为项目全局唯一路由表。

2. 手把手创建路由表文件(零报错步骤)

严格按步骤手动创建,杜绝路径、文件不存在报错:

1. 定位项目目录:src/main/resources/base

2. 无profile文件夹则:右键 base → New → Directory,命名为profile

3. 选中 profile 文件夹:右键 → New → File,全名创建router_map.json

路由表核心字段说明:

  • name:路由别名(代码跳转调用,大小写严格敏感)

  • pageSourceFile:页面ETS文件完整绝对路径

  • buildFunction:页面路由入口Builder函数名(必须和页面导出函数一致)

粘贴完整路由配置,一次性注册本篇所有页面,保证链路闭环:

{ "routerMap": [ { "name": "Start", "pageSourceFile": "src/main/ets/pages/Start.ets", "buildFunction": "StartBuilder" }, { "name": "Layout", "pageSourceFile": "src/main/ets/pages/Layout.ets", "buildFunction": "LayoutBuilder" } ] }

3. 全局页面创建统一强制规范(全程通用)

本项目所有页面统一创建规则,全程不变

✅ 唯一正确方式:右键 pages 目录 → New → ArkTS File,新建空白ETS文件

❌ 绝对禁止:使用右键自带的 Page、列表页、标签页等模板

(也可根据个人习惯)

删除线模板报错解释(新手必看)

模板带删除线 =废弃不兼容,这类模板是老旧FA模型专属,我们使用的是最新Stage模型,强行使用会出现API报错、路由失效、代码冗余冲突。

所有页面手写空白文件,架构干净、完全适配我们的自定义导航路由体系,无兼容问题。

4. 路由页面 Builder 函数强制规范

所有路由注册页面,必须导出全局@Builder入口函数,否则系统找不到页面,路由直接报错。

函数作用:作为路由跳转的唯一入口,供系统反射调用,绑定页面组件。

固定标准写法(所有页面通用):

// @Builder:构建器装饰器,用于路由注册页面入口 // export:必须导出,否则外部路由无法识别 @Builder export function 页面名Builder(name: string, param: string) { // 固定写法:实例化当前页面,接收路由传参 页面名({ name: name, value: param }); }

新建页面固定四步流程:新建空白ArkTS文件 → 编写页面组件 → 编写导出Builder入口函数 → 路由表注册。

重要说明@Builder、@Component、@Entry、Stack、Image、Button、Alignment、Color均为鸿蒙全局内置API,无需手动导入,强行导入会直接编译报错。

三、第二步:搭建全局导航骨架(Index入口页)

Index页面是整个APP的唯一入口根容器,核心作用是通过AppStorageV2全局挂载导航栈,实现全项目页面导航栈共享,彻底解决多页面栈冲突、跳转失效问题,统一托管所有页面路由跳转。

Index.ets 创建与完整代码

文件位置:src/main/ets/pages/Index.ets

创建方式:默认自带,缺失则右键pages新建ArkTS文件,命名Index

清空默认代码,粘贴以下带完整注释、可直接运行的标准代码:

// AppStorageV2:全局状态持久化工具,实现跨页面共享导航栈 import { AppStorageV2 } from '@kit.ArkUI'; /** * 首页路由入口构建函数 * 适配全局路由体系,作为Index首页的路由注册入口 */ @Builder export function IndexBuilder() { Index(); } // APP全局唯一入口页面 @Entry @Component struct Index { /** * 全局共享导航栈 * 通过AppStorageV2全局挂载,实现项目所有页面跨页面共用同一个导航栈 * 避免多栈冲突、页面跳转失效、页面栈错乱问题 */ pageStack: NavPathStack = AppStorageV2.connect(NavPathStack, 'navStack', () => new NavPathStack())!; build() { // 全局导航根容器,托管项目所有路由页面 Navigation(this.pageStack) { // 根页面无需自定义UI,空列布局占位即可 Column() {} } // 铺满全屏 .width('100%') .height('100%') // 设置根容器透明,不遮挡下级页面UI .backgroundColor(Color.Transparent) // 全局扩展安全区,适配沉浸式全屏效果 .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]) // 隐藏系统原生顶部导航栏,全程自定义页面样式 .hideNavBar(true) // 根页面加载完成触发 .onAppear(() => { // 延迟500ms执行跳转,规避Navigation初始化未完成导致的跳转失效问题 setTimeout(() => { // 控制台打印日志,方便调试查看跳转状态 console.info('开始跳转到广告页'); // 根据路由名跳转至广告启动页 this.pageStack.pushPathByName("Start", null, false); }, 500); }) } }

四、第三步:广告启动页完整开发(Start.ets)

实现效果:全屏沉浸式广告背景 + 右上角跳过按钮 + 3秒自动跳转主页 + 手动点击立即跳转,符合主流APP启动逻辑。

1. 新建页面

文件位置:src/main/ets/pages/Start.ets

创建方式:右键pages新建空白ArkTS文件,命名Start

2. 核心规则

所有路由页面必须被 NavDestination 包裹,否则无法获取导航栈上下文,页面空白、跳转失效。

3. 最终带详细注释完整代码

//第一步 建立自定义入口函数 @Builder export function StartBuilder(name: string, param: string) { Start({ name: name, value: param }); } // 广告启动页组件 @Component export struct Start { // 定义导航栈实例,用于当前页面跳转 navPathStack: NavPathStack = new NavPathStack(); /** * 页面生命周期:页面即将显示时触发 * 作用:开启3秒自动跳转定时器 */ aboutToAppear(): void { setTimeout(()=>{ this.navPathStack.replacePathByName("Layout",null,false) },3000) } // 路由接收参数 name: string = ''; @State value: string = ''; build() { // 路由页面专属容器,必须包裹所有UI,用于承接导航上下文 NavDestination() { // 堆叠布局:实现底层背景图 + 上层按钮层级效果 Stack({alignContent:Alignment.TopEnd}){ // 全屏广告背景图 Image($rawfile("ad.png")) .width("100%").height("100%") // 安全区扩展:图片延伸至状态栏、底部手势栏,消除上下白边 .expandSafeArea([SafeAreaType.SYSTEM],[SafeAreaEdge.TOP,SafeAreaEdge.BOTTOM]) // 右上角跳过按钮 Button("跳过").backgroundColor(Color.Gray) .margin(15) .onClick(()=>{ //this.navPathStack.replacePathByName("Layout",null,false) this.navPathStack.pushPathByName("Layout",null,false) }) } } //.title("广告页") // ctx.pathStack 导航控制器放入this.navPathStack .onReady((ctx: NavDestinationContext) => { this.navPathStack = ctx.pathStack; }) } }

4. 跳转方式核心避坑详解

  • pushPathByName(弃用):入栈跳转,保留广告页栈,用户返回键会退回广告页,不符合商用APP逻辑

  • replacePathByName(全程使用):替换当前页面,销毁广告页栈,进入主页后返回直接退出APP,符合主流APP启动逻辑

五、第四步:搭建主页基础骨架(Layout.ets)

为保证项目完整连贯可运行,本篇直接落地Layout主页基础架构,绝非临时占位。下一篇博客将在此骨架上迭代底部Tab、首页轮播、推荐卡片等完整UI,全程复用本篇代码,无重构、无废弃。

1. 新建页面

文件位置:src/main/ets/pages/Layout.ets

创建方式:右键pages新建空白ArkTS文件,命名Layout

2. 带详细注释零报错完整骨架代码

// import { Recommend1 } from '../component/Recommend1' // import { FindPage } from '../component/FindPage'; // 定义一个类 interface TabClass { text : string, icon : ResourceStr } @Builder export function LayoutBuilder() { Layout(); // 对应你的 struct 名字 } @Component export struct Layout { navPathStack: NavPathStack = new NavPathStack() tabData: TabClass[] =[ {text:'推荐', icon: $rawfile('ic_recommend.svg')}, {text:'发现',icon:$rawfile('ic_find.svg')}, {text:'动态',icon:$rawfile('ic_moment.svg')}, {text: '我的', icon: $rawfile('ic_mine.svg')} ] @State textColorIndex : number = 0; @Builder tarBuilder(item: TabClass, index: number) { Column({ space: 5 }) { Image(item.icon).width(24).fillColor(this.textColorIndex===index?'#E85a88':'#63AAAA') Text(item.text).font({ size: 14 }).fontColor(this.textColorIndex===index?'#E85a88':'#63AAAA') } } build() { NavDestination() { // barPosition: BarPosition.End 菜单至于底部。 Tabs({ barPosition: BarPosition.End }) { ForEach(this.tabData, (item: TabClass, index) => { TabContent() { // 推荐页直接用你写好的 Recommend1 组件 if (index === 0) { // Recommend1() // 推荐 } else if (index === 1) { // FindPage() // 发现 } else { // 其他页面先放个占位文本 Column() { Text(`${item.text}页面`).fontSize(20) }.width('100%').height('100%').justifyContent(FlexAlign.Center) } }.tabBar(this.tarBuilder(item, index)) .backgroundColor('#131215') }) }.backgroundColor('#3B3F42') .onChange((index) => { this.textColorIndex = index }) }.onReady((ctx: NavDestinationContext) => { // 获取共享的导航栈 this.navPathStack = ctx.pathStack; }) } }

至此,项目完整启动链路彻底跑通:APP启动 → Index加载导航栈 → 自动进入Start广告页 → 3秒/手动跳转Layout主页,无报错、无空白、无异常回退。

效果展示:

六、新手专属:全套报错解决方案

  1. 报错:buildFunction 不存在排查:页面是否导出对应Builder函数、函数名和路由表大小写完全一致、文件路径无错误。

  2. 问题:广告页上下有白边,无法全屏排查:Image宽高100%、是否添加expandSafeArea安全区扩展代码。

  3. 问题:跳转后页面空白排查:路由页面是否包裹NavDestination、Builder函数是否添加 export 导出。

  4. 问题:返回键退回广告页排查:所有启动页跳转统一使用replacePathByName,禁止使用push。

  5. 问题:导入代码编译报错解决方案:组件、装饰器(Stack/Image/Button/@Builder/@Component等)均为全局内置,无需导入,仅保留导航、安全区专属API导入即可。

本篇总结

本篇完成了完整可运行的项目底层架构:统一页面创建规范、配置全局路由表、搭建全局导航栈、实现商用级全屏广告启动页、落地主页基础骨架,全程无冗余代码、无报错、无临时占位,保证项目连贯可迭代。

本篇所有代码、规范、架构将贯穿整个系列,后续所有功能均基于本篇骨架迭代,无需重构。

下篇预告

下一篇将基于当前Layout主页骨架,开发底部Tab选项卡、图标文字高亮、多页面切换、首页搜索栏、轮播图、音乐推荐卡片等完整静态UI界面。

http://www.jsqmd.com/news/1035700/

相关文章:

  • 2026年小批量慢走丝加工厂家推荐排行榜:高精度与微米级品质的匠心之选 - 品牌发掘
  • 3步掌握Stable Diffusion AI换脸插件ReActor的终极指南
  • 2026年6月东五环新房推荐:五大项目专业评测置业朝阳注意事项价格 - 品牌推荐
  • AI数学发现新范式:形式化证明与直觉建模的融合
  • 2026年重型货架生产厂家推荐:东莞市力达仓储设备有限公司全系产品供应 - 品牌推荐官
  • Microchip生态系统实战指南:从技术支持到供应链管理
  • 2026长沙望城奢侈品回收优选榜单|湘奢汇(望城店)领衔5家正规靠谱门店推荐(黄金+名包+名表+名酒) - 生活测评小能手
  • 2026长沙卖欧米茄名表避坑别乱出价!7家表行真实测评 - 薛定谔的梨花猫
  • 智能水表跨境OEM通信选型解析:全球统一计费IoT方案优势
  • 2026 苏州靠谱首饰回收店推荐|正规黄金钻石奢侈品回收门店地址实测 - 薛定谔的梨花猫
  • Voohu:车载以太网1000BASE-T1共模扼流圈的宽带阻抗匹配与信号完整性设计
  • 哈密装修实测|本土精工,环保家装!顶峰装饰靠谱吗?全屋整装/老房翻新/别墅大宅全测评 - 商业先知
  • 遗传算法工业落地核心:选择、交叉、变异算子的工程化设计
  • 2026吉林焊缝探伤检测权威机构排行 TOP 本地高频选择,无损检测 + UT+RT+PT 检测 附电话地址 - 中安检测集团
  • 3步实现免费AI视频修复:从模糊到高清的专业级解决方案
  • 智能系统静默失效:数据漂移与模型退化预警七法
  • 2026海南焊缝探伤检测权威机构排行 TOP 本地高频选择,无损检测 + UT+RT+PT 检测 附电话地址 - 中安检测集团
  • 昆明装修公司推荐TOP10本地靠谱家装品牌,适配不同预算与需求 - 装修新知
  • 安徽中考生必看,合肥中科信息工程学校综合情况详细解读 - 辛云教育资讯
  • Legacy iOS Kit终极指南:一键降级越狱旧款iPhone/iPad设备
  • 2026佛山焊缝探伤检测权威机构排行 TOP 本地高频选择,无损检测 + UT+RT+PT 检测 附电话地址 - 中安检测集团
  • 2026怀化焊缝探伤检测权威机构排行 TOP 本地高频选择,无损检测 + UT+RT+PT 检测 附电话地址 - 中安检测集团
  • B站缓存视频丢失怎么办?这款开源工具帮你一键转换为MP4永久保存
  • 苏州正达立电子科技:半导体设备/光刻胶/高端仪器销售与回收服务优选 - 品牌推荐官
  • 中小企业财务数字化:如何判断一套方案值不值得买
  • 上海名表出手怎么选靠谱商家?2026 线下实体逸程报价实在 - 逸程
  • 构建完整黄金流转链条,西安打造安全便民黄金回收体系 - 奢侈品交易观察员
  • GPT-5.5 vs Claude Opus 4.8,多文件代码解析谁更强?实测给你答案
  • 鹤乡大厦店河蟹鲜活度怎么看
  • 2026年贵州刺梨原汁加工与全产业链供应商深度指南:从源头工厂到全国市场的精准选型 - 优质企业观察收录