前言

在移动应用开发中,底部导航栏是用户界面中最重要的组件之一。它不仅提供了应用的主要功能入口,还直接影响着用户体验。本文将深入分析基于 HarmonyOS ArkTS 框架实现的底部导航栏,通过实际代码案例,带您掌握从数据结构设计到最终实现的完整流程。

一、项目背景与需求分析

1.1 应用场景

这是一个医疗相关的应用,包含四个主要功能模块:

  • 医院:医院信息展示
  • 科室:科室分类管理
  • 医生:医生信息查询
  • 我的:个人中心
1.2 技术选型
  • 框架:HarmonyOS ArkTS
  • 语言:TypeScript/ArkTS
  • UI组件:Tabs + TabContent
  • 状态管理:@State 装饰器

二、核心数据结构设计

2.1 接口定义
interface tabBarInfo {
  title: string,        // 导航项标题
  normalImg: ResourceStr,    // 默认状态图标
  selectedImg: ResourceStr   // 选中状态图标
}
设计亮点:
  • 使用 TypeScript 接口确保类型安全
  • 支持双状态图标(正常/选中)
  • 资源引用使用 ResourceStr 类型,符合 HarmonyOS 规范
2.2 数据初始化
tabs: tabBarInfo[] = [
  { 'title': '医院', 'normalImg': $r('app.media.hospital'), 'selectedImg': $r("app.media.hospital_active") },
  { 'title': '科室', 'normalImg': $r('app.media.department'), 'selectedImg': $r("app.media.department_active") },
  { 'title': '医生', 'normalImg': $r('app.media.doctor'), 'selectedImg': $r("app.media.doctor_active") },
  { 'title': '我的', 'normalImg': $r('app.media.profile'), 'selectedImg': $r("app.media.profile_active") }
]
技术要点:
  • 使用 $r() 函数引用应用资源
  • 资源命名规范:模块名_active 表示激活状态
  • 数组结构便于后续的 ForEach 遍历

三、状态管理实现

3.1 状态变量
@State currentIndex: number = 0
关键特性:
  • @State 装饰器实现响应式状态管理
  • 默认选中第一个标签页
  • 状态变化自动触发UI更新
3.2 状态更新机制
.onSelected((index: number) => {
  this.currentIndex = index
})
实现原理:
  • 听 Tabs 组件的 onSelected 事件
  • 实时更新 currentIndex 状态
  • 状态变化自动触发 tabBuilder 重新渲染

四、自定义组件构建

4.1 @Builder 装饰器
@Builder
tabBuilder(item: tabBarInfo, index: number) {
  Column() {
    Image(this.currentIndex === index ? item.selectedImg : item.normalImg)
      .size({ width: 25, height: 25 })

    Text(item.title)
      .fontColor(this.currentIndex === index ? '#007AFF' : '#6B6B6B')
      .fontSize(13)
      .margin({ top: 3 })
  }
}
技术亮点:
  • @Builder 装饰器创建可复用的UI组件
  • 条件渲染实现图标状态切换
  • 动态颜色变化增强视觉反馈

五、主界面布局实现

5.1 Tabs 组件配置
Tabs({ barPosition: BarPosition.End }) {
  ForEach(this.tabs, (item: tabBarInfo, index: number) => {
    TabContent() {
      Text(item.title).fontSize(30)
    }
    .tabBar(this.tabBuilder(item, index))
  })
}
核心配置:
  • barPosition: BarPosition.End:底部定位
  • ForEach 循环渲染标签页内容
  • tabBar() 绑定自定义的标签栏样式

六、整体代码实现过程

Index.ets文件

//约定底部导航栏数据结构
interface tabBarInfo {
  title: string, //标题
  normalImg: ResourceStr, //默认图标
  selectedImg: ResourceStr, //选中的图片

}


@Entry
@Component
struct Index {
  tabs: tabBarInfo[] = [
    { 'title': '医院', 'normalImg': $r('app.media.hospital'), 'selectedImg': $r("app.media.hospital_active") },
    { 'title': '科室', 'normalImg': $r('app.media.department'), 'selectedImg': $r("app.media.department_active") },
    { 'title': '医生', 'normalImg': $r('app.media.doctor'), 'selectedImg': $r("app.media.doctor_active") },
    { 'title': '我的', 'normalImg': $r('app.media.profile'), 'selectedImg': $r("app.media.profile_active") }]
  //默认第一个选中
  @State currentIndex: number = 0

  //自定义tabBuilder函数组件
  @Builder
  tabBuilder(item: tabBarInfo, index: number) {
    Column() {
      Image(this.currentIndex === index ? item.selectedImg : item.normalImg)
        .size({ width: 25, height: 25 })

      Text(item.title)
        .fontColor(this.currentIndex === index ? '#007AFF' : '#6B6B6B')
        .fontSize(13)
        .margin({ top: 3 })
    }

  }

  build() {
    Column() {

      Tabs({ barPosition: BarPosition.End }) {

        ForEach(this.tabs, (item: tabBarInfo, index: number) => {
          TabContent() {
            Text(item.title).fontSize(30)
          }
          .tabBar(this.tabBuilder(item, index))
        })

      }

      //设置页面不需要左右滑动切换,只点击tab切换
      .scrollable(false)
      //点击tab监听事件
      .onSelected((index: number) => {
        this.currentIndex = index
      })

    }
    .height('100%')
    //设置背景色
    .backgroundColor(0xf4f4f5)
    //设置沉浸式页面
    //官方文档:https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-immersive#section1052895593418
    .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
  }
}

七、运行效果截图

在这里插入图片描述

八、官方文档

  1. 沉浸式页面实现:https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-immersive#section1052895593418
  2. 选项卡 (Tabs):https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-navigation-tabs
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐