一、核心概念与定位
1. 组件本质
Navigation 是一种容器型组件,用于封装页面中的“导航区域”和“内容区域”,并具备与系统导航栈联动的能力,例如支持返回操作、页面跳转以及页面栈的管理。其主要功能包括:
- 统一管理应用的顶部导航栏、底部标签栏等导航结构;
- 简化页面之间的跳转逻辑与返回行为;
- 提供原生级别的导航交互体验,如滑动返回、导航栏动画等;
- 扩展支持菜单、侧边抽屉等功能模块。
2. 核心结构组成
一个完整的 Navigation 组件由以下四个关键部分构成:
- 导航栏(NavBar):位于页面顶部,通常包含标题、返回按钮及操作项;
titlenavBarWidthnavBarHeight - 内容区:展示页面主体内容的区域,常作为 Column 等布局组件的父容器;
Navigation() - 菜单(Menu):设置在导航栏右侧的下拉菜单,通过
属性引入,可接收 Menu 组件以实现更多操作选项;menu - 抽屉(Drawer):支持从左侧或右侧滑出的侧边面板,适用于二级导航或功能入口,通过
属性传入 Drawer 组件进行配置。drawer
3. 典型应用场景
- 应用主界面,集成顶部导航栏与底部标签栏的设计模式;
- 涉及多层级页面跳转的应用场景,依赖导航栈实现自然返回流程;
- 需要使用侧边抽屉进行分类导航的功能模块,如电商类应用的商品分类或设置菜单;
- 对多个页面的导航样式有统一视觉要求的项目。
二、基础用法(入门必掌握)
1. 最简示例:带标题的导航页面
typescript
运行
import router from '@ohos.router'; // 路由管理(页面跳转用)
@Entry
@Component
struct BasicNavigation {
build() {
// 外层 Navigation 包裹整个页面
Navigation() {
// 内容区:页面主要内容
Column() {
Text("导航页面的核心内容")
.fontSize(20)
.margin({ top: 50 })
}
.width('100%')
.height('100%')
}
// 导航栏标题(支持字符串或自定义组件)
.title("首页")
// 导航栏背景色
.navBarBackgroundColor('#ffffff')
// 导航栏标题样式
.titleFont({ size: 22, weight: FontWeight.Bold })
// 导航栏左侧返回按钮(仅二级页面需要,默认隐藏)
.backButton({
onClick: () => {
router.back(); // 返回上一页
}
})
}
}
关键属性说明:
:设置导航栏的标题内容,支持纯文本或自定义组件(如 Logo 加文字组合);title: string | CustomBuilder:定义导航栏背景颜色,默认采用系统主题色;navBarBackgroundColor: Color:配置标题的文字样式,包括字号、字重和颜色等;titleFont: Font:控制左侧返回按钮的行为,backButton: BackButtonOptions用于绑定返回事件逻辑,onClick控制按钮的显示与隐藏状态。visibility
2. 导航栏右侧菜单(Menu)
可通过
menu
属性在导航栏右侧添加下拉菜单,支持图标、文字以及嵌套子菜单:
typescript
运行
Navigation() {
// 内容区...
}
.title("消息中心")
// 右侧菜单
.menu([
{
label: "刷新",
icon: $r('app.media.ic_refresh'), // 图标资源
onClick: () => {
console.log("触发刷新操作");
}
},
{
label: "筛选",
subMenu: [ // 子菜单
{ label: "未读", onClick: () => {} },
{ label: "已读", onClick: () => {} }
]
},
{
label: "设置",
icon: $r('app.media.ic_setting'),
enabled: false // 禁用菜单
}
])
菜单核心配置项:
:菜单显示的文字内容;label: string:菜单图标资源,需提前在icon: Resource中完成资源配置;main_pages.json:菜单点击时触发的回调函数;onClick: () => void:定义子菜单结构,支持多级嵌套;subMenu: MenuItem[]:是否启用菜单功能,默认值为enabled: boolean;true:控制菜单当前的展开/收起状态,默认为visibility: Visibility。Visibility.Visible
3. 侧边抽屉(Drawer)
利用
drawer
属性可添加侧边抽屉,支持左滑或右滑弹出,常用于构建二级导航或快捷功能入口:
typescript
运行
Navigation() {
// 内容区...
}
.title("首页")
// 侧边抽屉配置
.drawer({
// 抽屉标题
title: "导航菜单",
// 抽屉位置(Left/Right,默认 Left)
position: DrawerPosition.Left,
// 抽屉宽度(默认 280vp)
width: 300,
// 抽屉背景色
backgroundColor: '#f5f5f5',
// 抽屉内容(自定义布局)
content: () => {
Column() {
// 抽屉头部(如用户信息)
Row() {
Image($r('app.media.ic_avatar'))
.width(60)
.height(60)
.borderRadius(30)
Text("用户名")
.fontSize(18)
.marginLeft(15)
}
.padding(20)
.width('100%')
// 抽屉菜单列表
List() {
ListItem() { Text("首页").padding(15) }.onClick(() => {})
ListItem() { Text("我的订单").padding(15) }.onClick(() => {})
ListItem() { Text("收藏夹").padding(15) }.onClick(() => {})
ListItem() { Text("设置").padding(15) }.onClick(() => {})
}
.width('100%')
}
},
// 抽屉触发方式(Click/ Slide,默认 Click+Slide)
enableMode: DrawerEnableMode.Multiple,
// 抽屉按钮(导航栏左侧图标)
icon: $r('app.media.ic_menu')
})
抽屉核心配置项:
:抽屉内部的内容布局,必须提供自定义组件;content: () => void:设定抽屉滑出方向,可选position: DrawerPosition或Left;Right:设置抽屉宽度,推荐范围为 250–350vp;width: Length:用于在导航栏中显示触发抽屉的图标;icon: Resource:定义触发方式,可选仅点击图标enableMode: DrawerEnableMode、仅滑动手势Click,或两者皆支持Slide;Multiple:是否启用遮罩层,默认为mask: boolean。true
三、高级特性(实战核心)
1. 自定义导航栏(完全自定义 NavBar)
默认提供的导航栏样式较为固定,若需更灵活的 UI 表现,可通过
customNavBuilder
属性完全自定义导航栏布局:
typescript
运行
Navigation() {
// 内容区...
}
// 完全自定义导航栏
.customNavBuilder(() => {
Row() {
// 左侧返回按钮
Button() {
Image($r('app.media.ic_back'))
.width(24)
.height(24)
}
.backgroundColor(Colors.transparent)
.onClick(() => router.back())
// 中间标题(占满剩余空间)
Text("自定义导航栏")
.fontSize(20)
.fontWeight(FontWeight.Bold)
.flexGrow(1)
.textAlign(TextAlign.Center)
// 右侧操作按钮(两个图标)
Row() {
Image($r('app.media.ic_search'))
.width(24)
.height(24)
.marginRight(20)
Image($r('app.media.ic_share'))
.width(24)
.height(24)
}
}
.padding({ left: 15, right: 15 })
.width('100%')
.height(56) // 导航栏高度(建议与系统一致,默认 56vp)
.backgroundColor('#ffffff')
})
注意事项:
- 启用自定义导航栏后,原有的
、title、menu等属性将不再生效;backButton - 建议保持导航栏高度为 56vp,与系统默认值一致,避免出现适配问题;
- 需手动处理返回逻辑及状态栏适配问题,参考下方“状态栏一体化”章节。
2. 状态栏与导航栏一体化
鸿蒙系统支持将导航栏与状态栏背景融合,实现沉浸式视觉效果。通过
statusBarColor
和
navBarBackgroundColor
统一设置背景颜色:
typescript
运行
Navigation() {
// 内容区...
}
.title("沉浸式导航")
// 状态栏颜色(与导航栏一致)
.statusBarColor('#2f54eb')
// 导航栏颜色(与状态栏一致)
.navBarBackgroundColor('#2f54eb')
// 标题和图标颜色(状态栏文字/图标颜色)
.titleFont({ color: Colors.white })
.backButton({
icon: $r('app.media.ic_back_white'), // 白色返回图标
onClick: () => router.back()
})
.menu([
{ label: "分享", icon: $r('app.media.ic_share_white'), onClick: () => {} }
])
关键说明:
:设置状态栏背景色,默认为透明;statusBarColor: Color- 状态栏内的文字与图标颜色会根据
的明暗自动调整(深色背景显示白色文字,浅色背景显示黑色文字);statusBarColor - 也可通过
API 手动控制状态栏文字颜色:window
typescript
运行
import window from '@ohos.window';
// 在页面生命周期 onPageShow 中设置
onPageShow() {
window.getLastWindow().then((win) => {
// 设置状态栏文字颜色(Light/ Dark)
win.setStatusBarFontColor(Colors.white);
});
}
3. 结合 Router 实现页面跳转与导航栈管理
Navigation 与鸿蒙的
router
路由 API 深度集成,支持 push/pop 操作管理页面栈,且导航栏的返回按钮能自动响应路由状态变化。
步骤 1:配置路由文件(main_pages.json)
json
{
"src": [
"pages/Index.ets", // 首页(栈底)
"pages/Detail.ets" // 详情页(栈顶)
]
}
步骤 2:从首页跳转至详情页
typescript
运行
// Index.ets(首页)
Navigation() {
Button("跳转到详情页")
.onClick(() => {
// 路由跳转(push 新页面到栈顶)
router.pushUrl({
url: "pages/Detail.ets", // 目标页面路径
params: { id: 123 } // 传递参数
});
})
}
.title("首页")
步骤 3:从详情页返回首页
typescript
运行
// Detail.ets(详情页)
@Entry
@Component
struct DetailPage {
// 接收路由参数
private params = router.getParams();
build() {
Navigation() {
Text(`详情页 ID: ${this.params.id}`)
.fontSize(20)
}
.title("详情页")
// 自动显示返回按钮(点击触发 router.back())
.backButton({
onClick: () => router.back()
})
}
}
路由与 Navigation 联动特性总结:
- 页面栈中存在上一级页面时,返回按钮自动可见;
- 通过路由 API 进行页面跳转时,Navigation 自动更新导航栏状态;
- 支持滑动返回手势与物理返回键的同步响应。
4. 底部标签导航(TabBar + Navigation)
结合
Tabs
组件可实现常见的底部标签导航布局(多用于应用主页面),每个标签页对应独立的 Navigation 实例:
typescript
运行
@Entry
@Component
struct TabNavigation {
// 选中的标签索引
@State currentIndex: number = 0;
build() {
Tabs({ index: this.currentIndex })
.onChange((index) => {
this.currentIndex = index;
})
.barPosition(BarPosition.Bottom) // 标签栏在底部
.height('100%') {
// 标签页 1:首页
TabContent() {
Navigation() {
Text("首页内容")
}
.title("首页")
}
.tabBar({
icon: $r('app.media.ic_home'),
selectedIcon: $r('app.media.ic_home_selected'),
text: "首页"
})
// 标签页 2:消息
TabContent() {
Navigation() {
Text("消息内容")
}
.title("消息")
}
.tabBar({
icon: $r('app.media.ic_message'),
selectedIcon: $r('app.media.ic_message_selected'),
text: "消息"
})
// 标签页 3:我的
TabContent() {
Navigation() {
Text("我的内容")
}
.title("我的")
}
.tabBar({
icon: $r('app.media.ic_mine'),
selectedIcon: $r('app.media.ic_mine_selected'),
text: "我的"
})
}
}
}
关键说明:
- 每个 Tab 页面应包裹各自的 Navigation,确保导航栈隔离;
- 切换 Tab 时不触发页面栈 push,避免历史记录混乱;
- 推荐配合懒加载机制优化性能。
四、常见问题与避坑指南
- 导航栏高度适配问题:未正确设置高度可能导致布局错位,建议维持 56vp 的标准高度,并注意状态栏叠加影响。
- 抽屉无法滑动触发:检查
是否设置为支持滑动(enableMode: DrawerEnableMode或Slide),同时确认内容区域未拦截手势事件。Multiple - 路由跳转后返回按钮不显示:请确认页面栈中确实存在前一页,且未手动禁用返回按钮(
设置为 false)。visibility - 状态栏文字颜色不生效:系统会依据导航栏背景色自动判断文字颜色,若需强制指定,请调用
API 显式设置。window
系统默认的导航栏高度为 56vp,建议在自定义导航栏时保持此高度,以防止与状态栏或内容区域发生重叠;
若需调整高度,可通过 属性进行设置(仅支持 API 9+):navBarHeight
typescript
运行
检查 是否被设置为 enableMode 或 DrawerEnableMode.Slide;Multiple
抽屉组件应确保其宽度不超过屏幕的 80%(过宽可能导致滑动失效);
为避免内容区中的滑动组件(如 List、Scroll)与抽屉滑动产生冲突,可使用 对滑动范围进行限制。touchRegion
确认页面跳转方式采用的是 (而非 router.pushUrl,因为 replace 会替换当前页面,导致路由栈中无历史记录);router.replaceUrl
手动配置 的显示行为:backButton
typescript
运行
颜色需与文字形成足够对比度(例如深色背景搭配白色文字);statusBarColor
注意部分设备不支持手动设置状态栏文字颜色,需依赖系统自动适配;
应在 生命周期回调中调用 onPageShow API,确保页面显示后设置才生效。window
每个 可嵌套一个独立的 TabContent,实现标签页内部的独立导航逻辑;Navigation
通过 配置标签图标的选中与未选中状态以及对应的文字内容;tabBar
中的 Tabs 负责监听标签切换事件,并同步更新当前激活的索引值。onChange
返回操作将触发当前页面销毁并跳转至上一页面,同时导航栏自动切换为上一页的标题和样式;
支持多级页面跳转(例如 A→B→C),返回时按栈结构依次出栈(C→B→A)。
五、API 版本兼容性说明
| 特性 | 支持 API 版本 | 备注 |
|---|---|---|
| 基础导航栏(title、backButton) | API 8+ | 核心功能,全版本支持 |
| 自定义导航栏(customNavBuilder) | API 9+ | API 8 不支持,需降级使用默认导航栏 |
| 抽屉(Drawer) | API 8+ | 部分属性(如 enableMode)需 API 9+ |
| 菜单(Menu) | API 8+ | 子菜单(subMenu)需 API 9+ |
| 状态栏颜色(statusBarColor) | API 9+ | API 8 需通过 window API 间接设置 |
六、实战总结
Navigation 是鸿蒙应用中页面的“骨架”,其核心价值体现在:统一导航结构、简化路由管理、提供原生交互体验。
开发实践中应注意以下要点:
- 简单页面优先使用默认导航栏,复杂场景下使用
进行自定义;customNavBuilder - 多层级跳转依赖
实现路由控制,并与 Navigation 协同完成返回逻辑;router - 底部标签式导航可通过
组合构建,每个标签页拥有独立的导航栈;Tabs + Navigation - 注意不同 API 版本间的兼容性,避免因使用高版本特性导致低版本设备崩溃。
backButton
visibility
router.back()
TabContent
Navigation
tabBar
Tabs
onChange
navBarHeight
.navBarHeight(60) // 自定义导航栏高度
enableMode
DrawerEnableMode.Slide
Multiple
width
touchRegion
router.pushUrl
router.replaceUrl
visibility: Visibility.Visible
.backButton({
visibility: Visibility.Visible,
onClick: () => router.back()
})
statusBarColor
onPageShow
window
customNavBuilder
router
Tabs + Navigation

雷达卡


京公网安备 11010802022788号







