HarmonyOS ArkTS 选项卡导航(Tabs)全面指南

56 阅读4分钟

HarmonyOS ArkTS 选项卡导航(Tabs)全面指南

鸿蒙第四期开发者活动

选项卡导航是移动/平板/大屏应用中最常见的 UI 模式之一。它让用户在同一页面内快速切换不同的内容区域,同时保持 UI 结构清晰。HarmonyOS ArkTS 提供了 Tabs 组件来优雅实现这种效果。developer.huawei.com


一、Tabs 的基本结构

在 ArkUI/ArkTS 中,一个完整的 Tabs 结构由两部分组成:

  1. TabBar:顶部或底部的选项卡标签导航条
  2. TabContent:对应每个标签下显示的内容区域

Tabs 把多个 TabContent 组合在一起,每个 TabContent 对应一个标签;用户点击 TabBar 中的标签,就切换对应的 TabContent 显示。developer.huawei.com

基本结构长这样:

 Tabs() {
   TabContent().tabBar('标签A') {
     Text('这是标签A对应的内容')
   }
   TabContent().tabBar('标签B') {
     Text('这是标签B对应的内容')
   }
   TabContent().tabBar('标签C') {
     Text('这是标签C对应的内容')
   }
 }

二、Tabs 的核心理念

Tabs 的工作机制其实很直观:

  • TabBar 是按钮组:用户点击某个标签
  • TabContent 是面板组:每个标签对应一个内容面板
  • 点击标签就把对应的内容面板显示出来,其他面板隐藏
  • 同一个 Tabs 容器内部,TabBar 和 TabContent 关联紧密

这种结构特别适合把逻辑相近、但只需一个内容区展示的多个页面组合起来,例如 “首页/搜索/通知/我的” 这种底部导航;或顶部 Tab 的“最新/热门/关注”。developer.huawei.com


三、最简单的 Tabs 示例

这段代码展示了如何写一个横向的选项卡导航:

 Tabs() {
   TabContent().tabBar('首页') {
     Text('这里是首页内容')
   }
   TabContent().tabBar('分类') {
     Text('这里是分类内容')
   }
   TabContent().tabBar('我的') {
     Text('这里是个人中心')
   }
 }

几个要点:

  • 每个 TabContent 都需要 .tabBar(...)
  • .tabBar(...) 可以是文本,也可以是图标 + 文本组合
  • Tabs 容器会自动处理切换逻辑,本质就是把不同 TabContent 展示/隐藏切换掉 developer.huawei.com

四、自定义 TabBar(更灵活的导航栏外观)

默认 Tabs 只用字符串做标签,但很多项目需要:

  • 图标 + 文本
  • 激活态颜色变化
  • 自定义布局(例如图标上大下小的 Tab)

这时候可以用 CustomBuilder 方式来自定义 TabBar 外观。大致思路是:

  1. 定义一个 Builder 函数
  2. 根据当前 Tab 索引动态渲染不同状态样式
  3. TabContent().tabBar(...) 中传入这个 Builder

示例思路参考:

 @Builder
 tabBarBuilder(itemIndex: number, title: string, img: Resource, selImg: Resource) {
   Column() {
     Image(this.selectedIndex === itemIndex ? selImg : img)
       .width(30)
       .height(30);
     Text(title)
       .fontColor(this.selectedIndex === itemIndex ? Color.Red : Color.Gray)
       .fontSize(12);
   }
 }

再在 TabContent 里这样用:

 TabContent()
   .tabBar(this.tabBarBuilder(0, '首页', $r('icon_home'), $r('icon_home_sel')))

这样就可以自定义每个标签的展示形式了。cnblogs.com


五、Tabs 的事件监听与切换逻辑

Tabs 提供了几种事件监听方式,可以响应用户交互:

事件说明
onChange((index) => { ... })每次标签切换后触发
onTabBarClick((index) => { ... })点击 TabBar 的某一项触发(不一定切换成功)

例如:

 Tabs()
   .onChange((index: number) => {
     this.selectedIndex = index;
     console.log('当前活动标签索引:', index);
   })

注意:

  • onChange 不仅仅是点击触发,也可能是用户滑动切换触发
  • onTabBarClick 则更偏向“点击行为事件”,可做权限判断等逻辑 cnblogs.com

六、常见布局形式

1. 默认顶部 TabBar

这种形式最常见:标签在上,内容在下。

 Tabs() {
   TabContent().tabBar('标签1') { ... }
   TabContent().tabBar('标签2') { ... }
 }

2. 底部 TabBar(类似底部导航)

虽然 Tabs 默认是上方标签,但你可以通过样式或结合其他容器、布局方式让其变成“底部导航”的感觉。

示例做法通常是:

 Column() {
   // 内容区
   Tabs({ index: this.currentIndex }) { ... }.flex(1)
 ​
   // 下面手写 TabBar(也可以用 CustomBuilder)
   Row() { ... }
 }

这样就能把 TabBar 固定在底部,Tabs 内容区向上扩张。


七、为什么 Tabs 配合 Navigation 更好用

虽然 Tabs 自身能切换内容,但很多项目的页面逻辑更深层:

  • 点击某个 Tab 内某个列表项进入详情页
  • 从详情页返回仍然希望看到原来的 Tabs 和其状态

单独的 Tabs + Router 跳转 会让 TabBar 丢失或出现闪跳。更推荐:

Tabs 做多页主体结构 放在一个 Navigation 容器内,这样每个 Tab 内还能做深层导航(push/pop)并保持 TabBar 不变。Medium


八、实战建议与踩坑技巧

TabBar 选项个数不要太多

如果标签太多,界面拥挤甚至不可点击,建议采用 Scroll + 自定义 TabBar。


关联状态不要写全局变量

Tabs 内的当前索引应用 @State 去管理,这样组件才会自动刷新视图。


图标 + 文本组合要用 CustomBuilder

默认字符串式标签简单,但不够灵活。在 UI 设计中最好用 Builder 配合图标/文字一起渲染。


九、小结

Tabs 是实现多页面内容切换的核心组件,通过组合多个 TabContent 和一个 TabBar,可以快速做出顶部导航、底部导航或自定义导航栏:

✔ 每个 TabContent 绑定一个标签 ✔ onChange/onTabBarClick 控制交互逻辑 ✔ CustomBuilder 定制样式 ✔ 推荐配合 Navigation 做复杂页面栈管理