> 文档中心 > 【鸿蒙应用ArkTS开发系列】- 导航栏Tab组件使用讲解

【鸿蒙应用ArkTS开发系列】- 导航栏Tab组件使用讲解

目录

    • Tabs介绍
    • Tabs使用例子
    • TabBar 样式设置
      • 定义菜单样式对象-NavigationItem
      • 定义一个底部菜单栏集合数据-NavigationList
      • 修改TabBuilder
    • Tab 组件控制
    • 题外话

现在市场上的大部分应用,主页都是才用底部导航栏菜单作为页面主体框架来展示,
【鸿蒙应用ArkTS开发系列】- 导航栏Tab组件使用讲解
在鸿蒙中是使用Tabs组件实现,下面我们开始讲解Tab组件的使用。

Tabs介绍

Tabs是一个通过页签进行内容视图切换的容器组件,每个页签对应一个内容视图,它仅可包含子组件TabContent,同时搭配 TabsController使用。

TabsController 是Tabs组件的控制器,用于控制Tabs组件进行页签切换。不支持一个TabsController控制多个Tabs组件。
具体可查看官网介绍,这里就不多描述。

Tabs使用例子

@Entry@Componentexport struct MainPage {  @State mCurrentPage: number = 0;  private mTabController: TabsController = new TabsController()  build() {    Tabs({ barPosition: BarPosition.End, controller: this.mTabController }) {      TabContent() { Text('第一个页面')      }      .tabBar(this.TabBuilder(0))      TabContent() { Text('第二个页面')      }      .tabBar(this.TabBuilder(1))      TabContent() { Text('第三个页面')      }      .tabBar(this.TabBuilder(2))    }    .scrollable(true)    .vertical(false)    .barMode(BarMode.Fixed)    .onChange((index) => {      this.mCurrentPage = index;    })  }  @Builder TabBuilder(index: number) {    Column() {      Image(index == this.mCurrentPage ? $r('app.media.icon_selected'): $r('app.media.icon_normal')) .width('24vp') .height('24vp') .objectFit(ImageFit.Contain)      Text('菜单') .fontSize('10fp') .fontWeight(500) .fontColor(this.mCurrentPage === index ? $r('app.color.blue_3d9dff') : $r('app.color.gray_999999')) .margin({ top: '4vp' })    }.justifyContent(FlexAlign.Center)  }}

这里对上面代码进行讲解,

  1. 首先定义一个Tab容器组件,在其中摆放了三个TabContent子组件;
  2. 使用vertical属性跟barPosition: BarPosition.End配合即可以将导航栏显示在页面底部;
  3. 使用scrollable开启手势滑动切换tab页;
  4. 定义 onChange函数,可以监听tab页面切换事件,这里我们定义了一个全局变量记录当前tab显示子页索引,通过该值可对底部栏的图标跟文本进行样式高亮处理。
  5. 使用@Builder注解定义了一个TabBuilder的布局绘制方法,进行tab底部导航栏的绘制

上面代码是一个比较粗糙的例子,由于tabBar设置调用同一个TabBuilder,因此绘制后,每个底部菜单是一模一样的效果。

下面我们对其进行修改,让它支持多个不同菜单绘制

TabBar 样式设置

定义菜单样式对象-NavigationItem

export interface NavigationItem {  id: number;   text: Resource; //文本  icon_normal: Resource; // 默认图标  icon_selected: Resource; // 选中图标}

定义一个底部菜单栏集合数据-NavigationList

export const NavigationList: NavigationItem[] = [  {    icon_normal: $r('app.media.main_icon_home'),    icon_selected: $r('app.media.main_icon_home'),    text: $r('app.string.tab_home'),    id: 0  },  {    icon_normal: $r('app.media.main_icon_life'),    icon_selected: $r('app.media.main_icon_life'),    text: $r('app.string.tab_life'),    id: 1  },  {    icon_normal: $r('app.media.main_icon_user'),    icon_selected: $r('app.media.main_icon_user'),    text: $r('app.string.tab_user'),    id: 2  },]

修改TabBuilder

@Builder TabBuilder(item: NavigationItem) {     Column() { Image(this.mCurrentPage === this.getTabIndexByItem(item) ? item.icon_selected : item.icon_normal)   .width('24vp')   .height('24vp')   .objectFit(ImageFit.Contain) Text(item.text)   .fontSize('10fp')   .fontWeight(500)   .fontColor(this.mCurrentPage === this.getTabIndexByItem(item) ? $r('app.color_blue_3d9dff') : $r('app.color.gray_999999'))   .margin({ top: '4vp' })      }      .justifyContent(FlexAlign.Center)      .width('100%')      .height('100%')    }  }

这里是根据NavigationItem ID动态找在数组中的索引。

getTabIndexByItem(navigationItem: NavigationItem): number {    return this.mTabDataList.findIndex(item => item.id === navigationItem.id);  }

通过传入一个NavigationItem,对TabBuilder中的组件样式进行动态配置。

Tab 组件控制

如果想要通过代码去控制tab切换到指定子页,可以使用 TabController来对tab进行控制,使用changeIndex函数进行切换。

题外话

本文到此结束,谢谢阅读,由于时间匆忙,只能进行简单讲解,一些tab滑动动画、tabItem的点击样式、tabbar分隔线的问题,后续有时间再进行补充。如有疑问,评论区沟通探讨。