全部版块 我的主页
论坛 数据科学与人工智能 人工智能
76 0
2025-11-28

一、核心概念与定位

1. 组件本质

Navigation 是一种容器型组件,用于封装页面中的“导航区域”和“内容区域”,并具备与系统导航栈联动的能力,例如支持返回操作、页面跳转以及页面栈的管理。其主要功能包括:

  • 统一管理应用的顶部导航栏、底部标签栏等导航结构;
  • 简化页面之间的跳转逻辑与返回行为;
  • 提供原生级别的导航交互体验,如滑动返回、导航栏动画等;
  • 扩展支持菜单、侧边抽屉等功能模块。

2. 核心结构组成

一个完整的 Navigation 组件由以下四个关键部分构成:

  • 导航栏(NavBar):位于页面顶部,通常包含标题、返回按钮及操作项;
    title
    navBarWidth
    navBarHeight
  • 内容区:展示页面主体内容的区域,常作为 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(); // 返回上一页
      }
    })
  }
}

关键属性说明:

  • title: string | CustomBuilder
    :设置导航栏的标题内容,支持纯文本或自定义组件(如 Logo 加文字组合);
  • 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
  • width: Length
    :设置抽屉宽度,推荐范围为 250–350vp;
  • 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
    的明暗自动调整(深色背景显示白色文字,浅色背景显示黑色文字);
  • 也可通过
    window
    API 手动控制状态栏文字颜色:
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,避免历史记录混乱;
  • 推荐配合懒加载机制优化性能。

四、常见问题与避坑指南

  1. 导航栏高度适配问题:未正确设置高度可能导致布局错位,建议维持 56vp 的标准高度,并注意状态栏叠加影响。
  2. 抽屉无法滑动触发:检查
    enableMode: DrawerEnableMode
    是否设置为支持滑动(
    Slide
    Multiple
    ),同时确认内容区域未拦截手势事件。
  3. 路由跳转后返回按钮不显示:请确认页面栈中确实存在前一页,且未手动禁用返回按钮(
    visibility
    设置为 false)。
  4. 状态栏文字颜色不生效:系统会依据导航栏背景色自动判断文字颜色,若需强制指定,请调用
    window
    API 显式设置。

系统默认的导航栏高度为 56vp,建议在自定义导航栏时保持此高度,以防止与状态栏或内容区域发生重叠;

若需调整高度,可通过

navBarHeight
属性进行设置(仅支持 API 9+):

typescript
运行

检查

enableMode
是否被设置为
DrawerEnableMode.Slide
Multiple

抽屉组件应确保其宽度不超过屏幕的 80%(过宽可能导致滑动失效);

为避免内容区中的滑动组件(如 List、Scroll)与抽屉滑动产生冲突,可使用

touchRegion
对滑动范围进行限制。

确认页面跳转方式采用的是

router.pushUrl
(而非
router.replaceUrl
,因为 replace 会替换当前页面,导致路由栈中无历史记录);

手动配置

backButton
的显示行为:

typescript
运行

statusBarColor
颜色需与文字形成足够对比度(例如深色背景搭配白色文字);

注意部分设备不支持手动设置状态栏文字颜色,需依赖系统自动适配;

应在

onPageShow
生命周期回调中调用
window
API,确保页面显示后设置才生效。

每个

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
    进行自定义;
  • 多层级跳转依赖
    router
    实现路由控制,并与 Navigation 协同完成返回逻辑;
  • 底部标签式导航可通过
    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

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群