《Navigation实现闪屏页》二、HarmonyOS_Navigation组件完全指南
HarmonyOS ArkUI Navigation组件完全指南:从入门到精通
本文基于 HarmonyOS NEXT(API 23+)开发环境,全面讲解 ArkUI Navigation 组件的使用方法,涵盖页面导航、路由管理、生命周期、转场动画等核心知识,帮助开发者构建现代化的导航架构。
效果
一、前言
在 HarmonyOS 应用开发中,页面导航是应用架构的骨架。ArkUI 提供了 Navigation 组件作为新一代导航方案,替代了传统的 router 模块,带来了更灵活的页面管理、更丰富的生命周期控制和更优雅的转场动画。
本文将从零开始,系统讲解 Navigation 组件的核心概念和实战用法。
二、Navigation 导航架构
2.1 三层架构
Navigation 采用清晰的三层架构设计:
Navigation(根容器)
├── NavBar(导航栏:标题、菜单、工具栏)
├── NavDestination(子页面容器,独立生命周期)
└── NavPathStack(页面栈管理器)
- Navigation:页面导航的根容器,管理导航栏和内容区域
- NavDestination:子页面的容器组件,每个目标页面独立管理
- NavPathStack:程序化控制页面栈,支持 push、pop、replace 等操作
2.2 导航模式
| 模式 | 触发条件 | 说明 |
|---|---|---|
| 单栏模式(Stack) | 屏幕宽度 < 600vp | 整页切换,适合手机 |
| 分栏模式(Split) | 屏幕宽度 >= 600vp | 左侧导航 + 右侧内容,适合平板 |
三、基础用法
3.1 最简 Navigation 示例
@Entry
@Component
struct NavigationDemo {
pathStack: NavPathStack = new NavPathStack();
build() {
Navigation(this.pathStack) {
// 首页内容(NavBar 区域)
Column() {
Text('首页')
.fontSize(28)
.fontWeight(FontWeight.Bold)
Button('跳转到详情页')
.margin({ top: 20 })
.onClick(() => {
// 通过 NavPathStack 推送新页面
this.pathStack.pushPath({
name: 'DetailPage',
param: { id: 1, title: '文章标题' }
});
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
.title('应用首页')
.navDestination(this.PageMap)
}
@Builder
PageMap(name: string, param: Object) {
NavDestination() {
DetailContent({ param: param })
}
.title('详情页')
}
}
3.2 配合路由表使用(推荐)
在实际项目中,推荐使用 route_map.json 配置路由表,实现页面解耦:
步骤1: 在 src/main/resources/base/profile/ 下创建 route_map.json:
{
"routerMap": [
{
"name": "DetailPage",
"pageSourceFile": "src/main/ets/pages/DetailPage.ets",
"buildFunction": "DetailBuilder",
"data": {
"description": "详情页面"
}
}
]
}
步骤2: 在目标页面文件中导出 @Builder 函数:
// DetailPage.ets
@Builder
export function DetailBuilder(name: string, param: Object) {
DetailPage();
}
@Entry
@Component
struct DetailPage {
build() {
NavDestination() {
Column() {
Text('详情页面内容')
.fontSize(20)
}
.width('100%')
.height('100%')
}
.hideTitleBar(true)
}
}
步骤3: 在 module.json5 中注册路由表:
{
"module": {
// ...
"pages": "$profile:main_pages",
"routerMap": "$profile:route_map"
}
}
步骤4: 使用 pushPathByName 跳转:
this.pathStack.pushPathByName('DetailPage', { id: 1 });
四、NavPathStack 页面栈管理
NavPathStack 是 Navigation 的核心,提供丰富的页面栈操作方法。
4.1 常用操作方法
@Entry
@Component
struct StackOperationDemo {
pathStack: NavPathStack = new NavPathStack();
build() {
Navigation(this.pathStack) {
Column({ space: 16 }) {
// 入栈:推送新页面
Button('Push 新页面')
.onClick(() => {
this.pathStack.pushPath({ name: 'SubPage', param: 'data' });
})
// 入栈(简写)
Button('Push by Name')
.onClick(() => {
this.pathStack.pushPathByName('SubPage', null);
})
// 替换当前页面
Button('Replace 当前页')
.onClick(() => {
this.pathStack.replacePath({ name: 'OtherPage' });
})
// 出栈:返回上一页
Button('Pop 返回')
.onClick(() => {
this.pathStack.pop();
})
// 出栈并返回结果
Button('Pop with Result')
.onClick(() => {
this.pathStack.pop({ result: 'success' });
})
// 返回到指定页面
Button('Pop to Name')
.onClick(() => {
this.pathStack.popToName('HomePage');
})
// 清空页面栈
Button('Clear All')
.onClick(() => {
this.pathStack.clear();
})
// 查询栈信息
Button('Stack Info')
.onClick(() => {
let size = this.pathStack.size();
let allNames = this.pathStack.getAllPathName();
console.info(`栈大小: ${size}, 页面: ${JSON.stringify(allNames)}`);
})
}
.width('100%')
.height('100%')
}
.navDestination(this.PageMap)
}
@Builder
PageMap() {
NavDestination() {
Text('子页面')
}
}
}
4.2 方法速查表
| 方法 | 说明 |
|---|---|
pushPath(info) |
入栈,携带参数 |
pushPathByName(name, param) |
按名称入栈 |
replacePath(info) |
替换当前页面 |
pop(param?) |
出栈,可返回结果 |
popToName(name) |
出栈到指定名称的页面 |
popToIndex(index) |
出栈到指定索引 |
clear() |
清空所有页面 |
size() |
获取栈大小 |
getAllPathName() |
获取所有页面名称 |
getCurrentIndex() |
获取当前页面索引 |
getParamByIndex(index) |
获取指定索引的参数 |
五、NavDestination 生命周期
NavDestination 提供完整的页面生命周期回调,是 Navigation 优于传统 router 的关键特性。
5.1 生命周期回调
@Builder
export function LifecycleBuilder(name: string, param: Object) {
LifecyclePage();
}
@Entry
@Component
struct LifecyclePage {
@State message: string = '页面初始化中...';
build() {
NavDestination() {
Column() {
Text(this.message)
.fontSize(18)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
.onReady((ctx: NavDestinationContext) => {
// 页面就绪:可以获取 pathStack 和参数
let param = ctx.pathInfo.param;
this.message = `就绪完成,参数: ${JSON.stringify(param)}`;
})
.onShown(() => {
// 页面显示:适合刷新数据或恢复动画
this.message = '页面已显示';
})
.onHidden(() => {
// 页面隐藏:适合暂停动画或保存状态
this.message = '页面已隐藏';
})
.onBackPressed(() => {
// 返回键拦截:返回 true 表示拦截默认行为
console.info('返回键被按下');
return false; // 不拦截,允许默认返回
})
}
}
5.2 生命周期顺序
onReady → onShown → (用户操作) → onHidden → (重新显示) → onShown → ...
| 回调 | 触发时机 | 典型用途 |
|---|---|---|
onReady |
页面创建并加入导航树后 | 初始化数据、获取参数 |
onShown |
页面变为可见时 | 刷新UI、恢复动画 |
onHidden |
页面被遮挡时 | 暂停任务、保存状态 |
onBackPressed |
返回键按下时 | 拦截返回、确认退出 |
六、导航栏配置
6.1 标题设置
Navigation(this.pathStack) {
// 首页内容
}
.title('应用标题')
.titleMode(NavigationTitleMode.Mini) // 紧凑标题模式
6.2 菜单配置
Navigation(this.pathStack) {
// 首页内容
}
.menus([
{
value: 'search',
icon: $r('app.media.ic_search'),
action: () => {
console.info('搜索被点击');
}
},
{
value: 'settings',
icon: $r('app.media.ic_settings'),
action: () => {
console.info('设置被点击');
}
}
])
6.3 工具栏配置
Navigation(this.pathStack) {
// 首页内容
}
.toolbar([
{ value: 'edit', icon: $r('app.media.ic_edit'), action: () => {} },
{ value: 'share', icon: $r('app.media.ic_share'), action: () => {} }
])
6.4 隐藏导航栏
在闪屏页等场景中,需要隐藏导航栏:
Navigation(this.pathStack) {
SplashContent()
}
.hideToolBar(true)
.hideNavBar(true) // 隐藏整个导航栏
七、转场动画
7.1 默认转场
Navigation 默认提供滑动转场动画,可以通过 transition 自定义:
NavDestination() {
Column() {
Text('自定义转场页面')
}
}
.transition(
TransitionEffect.OPACITY
.animation({ duration: 300, curve: Curve.EaseOut })
)
7.2 常用转场效果
// 淡入淡出
TransitionEffect.OPACITY.animation({ duration: 300 })
// 左滑进入
TransitionEffect.SLIDE_LEFT
// 右滑进入
TransitionEffect.SLIDE_RIGHT
// 组合效果:缩放 + 淡入
TransitionEffect.asSequence([
TransitionEffect.OPACITY.scale({ scale: 0.95 }),
TransitionEffect.OPACITY
])
八、实战示例:闪屏页导航架构
下面是一个典型的闪屏页 + 主页的导航架构示例:
// SplashPage.ets - 闪屏页入口
import { HomePage } from './HomePage';
@Builder
export function SplashBuilder(name: string, param: Object) {
SplashPage();
}
@Entry
@Component
struct SplashPage {
pageInfos: NavPathStack = new NavPathStack();
@State isHideNavBar: boolean = false;
private timerId: number = -1;
aboutToAppear(): void {
// 3秒后自动跳转到主页
this.timerId = setTimeout(() => {
this.isHideNavBar = true;
this.pageInfos.pushPathByName('HomePage', null, false);
}, 3000);
}
aboutToDisappear(): void {
if (this.timerId !== -1) {
clearTimeout(this.timerId);
}
}
// navDestination 构建器:路由双重保障
@Builder
PageMap(name: string, param: Object) {
if (name === 'HomePage') {
HomePage()
}
}
build() {
Navigation(this.pageInfos) {
Column() {
Image($r('app.media.splash_bg'))
.width('100%')
.height('100%')
.objectFit(ImageFit.Cover)
}
.width('100%')
.height('100%')
}
.hideToolBar(true)
.hideNavBar(this.isHideNavBar)
.backgroundColor('#020215')
.navDestination(this.PageMap)
}
}
// HomePage.ets - 主页(需 export 导出)
@Builder
export function HomeBuilder(name: string, param: Object) {
HomePage();
}
@Entry
@Component
export struct HomePage {
build() {
NavDestination() {
Column() {
Text('欢迎来到主页')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.fontColor('#e2e8f0')
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
.linearGradient({
angle: 180,
colors: [['#020215', 0.0], ['#06062a', 0.5], ['#080828', 1.0]]
})
}
.backgroundColor('#020215')
.hideTitleBar(true)
}
}
架构要点:
- 闪屏页作为 Navigation 的根内容,隐藏导航栏
- 通过
pushPathByName跳转到主页,animated: false关闭动画 - 主页使用
NavDestination容器,通过onReady获取 pathStack - 在
aboutToDisappear中清理定时器,防止内存泄漏 - 双重路由保障:同时使用
route_map.json+navDestination构建器,确保路由可靠解析 - Navigation 设置背景色:
.backgroundColor('#020215')防止系统默认背景色透出 - NavDestination 设置背景色:
.backgroundColor('#020215')覆盖默认黄色背景 - 主页 struct 必须 export:被闪屏页
navDestination构建器直接导入引用
九、最佳实践
| 实践 | 说明 |
|---|---|
| 使用 route_map.json | 页面解耦,便于维护和团队协作 |
| navDestination 双重保障 | 同时配置 route_map.json 和 navDestination 构建器,防止路由解析失败 |
| 避免使用 router 模块 | router 已废弃,新项目统一使用 Navigation |
| NavDestination 单根组件 | 每个 Builder 必须返回单个根组件 |
| NavDestination 设置背景色 | 显式设置 backgroundColor,防止系统默认黄色背景透出 |
| Navigation 设置背景色 | 根容器也需设置背景色,避免转场时露出默认底色 |
| 目标页面 struct 加 export | 被 navDestination 构建器导入时必须导出 |
| 传递轻量参数 | 只传 ID 等轻量数据,大数据在目标页加载 |
| 清理定时器 | 在 aboutToDisappear 中清理,防止内存泄漏 |
| 合理使用生命周期 | 在 onReady 初始化,onHidden 暂停 |
十、总结
Navigation 是 HarmonyOS 推荐的导航方案,提供了清晰的三层架构、强大的 NavPathStack 栈管理和丰富的生命周期控制。本文从基础用法到实战架构,系统讲解了 Navigation 的核心知识点。
关键要点回顾:
- Navigation 是根容器,NavDestination 是子页面容器
- NavPathStack 管理页面栈:push、pop、replace、clear
- 生命周期回调:onReady、onShown、onHidden、onBackPressed
- 使用 route_map.json + navDestination 双重路由保障
- 闪屏页场景:hideNavBar + pushPathByName 跳转
- Navigation 和 NavDestination 都需显式设置 backgroundColor
- 被引用的页面 struct 必须加 export 关键字
更多推荐




所有评论(0)