一、前言:

在移动APP开发中,底部导航栏是一种常见的用户界面设计元素,主要用于提供快速访问应用核心功能的入口,绝大部分APP都会设计底部导航栏,只有少数APP没有或没必要用到。它的作用和设计要点如下:

1、核心作用

快速导航

  • 允许用户一键切换应用的主要模块(如首页、发布和个人中心等),避免频繁返回上级页面。
  • 适合功能复杂、模块划分清晰的应用(如社交、电商、工具类APP)。

明确核心功能

  • 通过图标和文字标签突出展示最重要的3-5个功能入口,降低用户学习成本。

保持操作一致性

  • 固定显示在屏幕底部,符合用户习惯,减少误操作。

  • HarmonyOS在“一次开发,多端部署”的特性下,建议大屏时把导航栏放在左侧,这样右侧可用面积更好。

提升用户体验

  • 避免用户迷失在多层页面中,随时可返回核心页面。

2、设计规范

数量控制

  • 通常放置3-5个常用核心标签,过多会显得拥挤。

视觉反馈

  • 选中态(高亮颜色、图标变化)明确当前所在模块。

图标+文字

  • 纯图标易歧义,需搭配简短标签(如“首页”“我的”);个别页签可以不用加文字说明(如“发布”),而且这个按钮可以更加丰富界面。

 

二、正题:

前言说完,也该进入我们今天的正题了。这一节,我们将从默认样式讲起,这也是大部分有底部导航栏的APP使用的样式。新建项目后,我们只需要在entry/src/main/ets/pages/Index.ets或MainPage.ets 里面加相关代码便可实现导航栏功能

预览效果:

 

1、核心组件:

  • Tabs

2、核心代码:

Tabs({ barPosition: BarPosition.End, index: this.currentIndex, controller: this.controller }) {
    TabContent() {
        ...
    }.tabBar(...)
    ...
}.vertical(false)

1)Tabs里面的属性barPosition需要选择:BarPosition.End并且vertical选择false,这样该样式才会置于底部并且是横向的。

2)一个Tabs里面可以包含多个TabContent(),但是最好不超过5个。

代码解析:

// 选择的页签下标
@State selectedIndex: number = 0;

// 当前页签下标
@State currentIndex: number = 0;

// 页签控制器
private controller: TabsController = new TabsController();


// 自定义函数,方便.tabBar()函数复用
@Builder
tabBuilder(title: string, targetIndex: number, selectImg: ResourceStr, unselectImg: ResourceStr) {
    Column() {
      Image(this.selectedIndex === targetIndex ? selectImg : unselectImg)
        .width(24)
        .height(24)
        .margin({ bottom: 4 })
        .objectFit(ImageFit.Contain)
      Text(title).fontColor(this.selectedIndex === targetIndex ? '#1296db' : '#707070')
    }.width('100%')
    .height(50)
    .justifyContent(FlexAlign.Center)
}


// onChange()当点击页签时,获取并改变下标值
Tabs() {
    ...
}
.onChange((index: number) => {
        this.currentIndex = index;
        this.selectedIndex = index;
      })

三、完整代码:

@Entry
@Component
struct Index {
  @State selectedIndex: number = 0;
  @State currentIndex: number = 0;
  private controller: TabsController = new TabsController();

  @Builder
  tabBuilder(title: string, targetIndex: number, selectImg: ResourceStr, unselectImg: ResourceStr) {
    Column() {
      Image(this.selectedIndex === targetIndex ? selectImg : unselectImg)
        .width(24)
        .height(24)
        .margin({ bottom: 4 })
        .objectFit(ImageFit.Contain)
      Text(title).fontColor(this.selectedIndex === targetIndex ? '#1296db' : '#707070')
    }.width('100%')
    .height(50)
    .justifyContent(FlexAlign.Center)
  }

  build() {
    Column() {
      Tabs({ barPosition: BarPosition.End, index: this.currentIndex, controller: this.controller }) {
        TabContent() {
          Column() {
            Text('首页的内容')
              .fontSize(30)
          }
          .width('100%')
          .height('100%')
          .backgroundColor('#00CB87')
          .justifyContent(FlexAlign.Center)
        }.tabBar(this.tabBuilder('首页', 0, $r('app.media.ic_tabbar_home_on'), $r('app.media.ic_tabbar_home_off')))


        TabContent() {
          Column() {
            Text('发布的内容')
              .fontSize(30)
          }
          .width('100%')
          .height('100%')
          .backgroundColor('#007DFF')
          .justifyContent(FlexAlign.Center)
        }
        .tabBar(this.tabBuilder('发布', 1, $r('app.media.ic_tabbar_publish_on'), $r('app.media.ic_tabbar_publish_off')))


        TabContent() {
          Column() {
            Text('我的内容')
              .fontSize(30)
          }
          .width('100%')
          .height('100%')
          .backgroundColor('#E67C92')
          .justifyContent(FlexAlign.Center)
        }
        .tabBar(this.tabBuilder('我的', 2, $r('app.media.ic_tabbar_my_on'), $r('app.media.ic_tabbar_my_off')))
      }
      .barWidth(360)
      .barHeight(60)
      .vertical(false)
      .barMode(BarMode.Fixed)
      .animationDuration(0)
      .backgroundColor('#F1F3F5')
      .onChange((index: number) => {
        this.currentIndex = index;
        this.selectedIndex = index;
      })
    }
    .width('100%')
    .height('100%')
  }
}

代码路径:https://gitcode.com/RybinWu/DiverseTabbar

Logo

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

更多推荐