引言

在之前开发的页面中,每个页面都是单视图的独立内容。然而,常见的应用主界面都支持通过点击或滑动在不同视图间切换。这类对页面内容进行分类、提高页面空间利用率的多视图切换场景,一般使用选项卡 Tabs 组件来实现。本节课将系统讲解 Tabs 组件的定义、结构、属性、三种布局类型以及自定义 TabBar 的开发方法,最终实现可切换的底部导航主界面。

核心内容

Tabs 组件基础认知

Tabs 是通过页签进行内容视图切换的容器组件,每个页签对应一个独立的内容视图,用于对页面内容分类、提升页面空间利用率、实现多视图切换。

组件组成:Tabs 由内容区 TabContent 和导航页签栏 TabBar 两部分组成。

应用场景:常见于应用首页切换、图库分类浏览、时钟多城市展示等场景。

常见布局类型

布局类型 说明
顶部导航栏 导航位于页面顶部,页签横向排列,常见于分类内容浏览
底部导航栏 导航位于页面底部,页签横向排列,是应用主界面最常用的布局
侧边导航栏 导航位于页面侧边,页签纵向排列,多用于平板横屏场景

导航位置通过 barPosition 参数控制,排列方向通过 vertical 属性控制,两种配置组合即可实现三种布局。

Tabs 组件接口与属性

组件接口定义
Tabs(value: { barPosition?: BarPosition, index?: number, controller?: TabsController })
参数 说明 默认值
barPosition 设置 Tabs 的页签位置,可选值为 Start(顶部/左侧)和 End(底部/右侧) Start
index 设置初始显示页签的索引 0
controller 设置 Tabs 控制器,用于控制 Tabs 组件进行页签切换 -
核心属性
属性名称 说明
vertical 设置 Tabs 方向是否为纵向,默认值为 false(横向排列)
barMode 设置 TabBar 布局模式,包含 Fixed 和 Scrollable 两种
barWidth 设置 TabBar 的总宽度
barHeight 设置 TabBar 的总高度

barMode 两种模式的区别

模式 说明
Fixed 所有 TabBar 页签平均分配宽度,适配页数较少的导航
Scrollable TabBar 使用实际布局宽度,超出总长度后可滑动浏览,适配页数较多的导航

Tabs 与 TabContent 的结构关系

层级结构规则

  1. Tabs 作为父容器,使用花括号包裹多个 TabContent 子组件。

  2. 每个 TabContent 对应一个独立的内容视图,需要通过 .tabBar() 属性配置对应页签的显示内容。

  3. 多个 TabContent 需要按照顺序在 Tabs 内依次放置。

TabContent 不支持设置独立的宽高属性,宽度默认撑满父组件 Tabs,高度由父组件 Tabs 高度减去 TabBar 高度自动决定。

基础示例代码

Tabs() {
    TabContent() {
        Text('首页的内容').fontSize(30)
    }
    .tabBar('首页')

    TabContent() {
        Text('推荐的内容').fontSize(30)
    }
    .tabBar('推荐')

    TabContent() {
        Text('发现的内容').fontSize(30)
    }
    .tabBar('发现')

    TabContent() {
        Text('我的内容').fontSize(30)
    }
    .tabBar('我的')
}

不同导航布局的实现配置

布局类型 barPosition 配置 vertical 配置
顶部导航 BarPosition.Start false(横向)
底部导航 BarPosition.End false(横向)
侧边导航 BarPosition.Start true(纵向)

自定义 TabBar 实现步骤

在实际开发中,Tabs 默认页签样式通常无法满足 UI 设计需求,此时需要自定义 TabBar 样式。

实现思路

使用 @Builder 装饰器自定义 TabBar 样式,通过状态变量控制选中态样式,配合 TabsController 实现切换。

实现步骤

1. 定义状态变量与控制器

@State currentIndex: number = 0;
private tabsController: TabsController = new TabsController();

2. 使用 @Builder 定义自定义 TabBar

@Builder
tabBuilder(title: string, index: number, icon: Resource) {
    Column() {
        Image(icon)
            .width(24)
            .height(24)
            .fillColor(this.currentIndex === index ? '#007dff' : '#999999')
        Text(title)
            .fontSize(12)
            .fontColor(this.currentIndex === index ? '#007dff' : '#999999')
    }
    .onClick(() => {
        this.tabsController.changeIndex(index);
    })
}

3. 在 Tabs 中使用自定义 TabBar

Tabs({
    barPosition: BarPosition.End,
    controller: this.tabsController
}) {
    TabContent() {
        // 首页内容
    }
    .tabBar(this.tabBuilder('首页', 0, $r('app.media.ic_home')))

    TabContent() {
        // 设置页内容
    }
    .tabBar(this.tabBuilder('我的', 1, $r('app.media.ic_mine')))
}
.barWidth('100%')
.barHeight(56)
.barMode(BarMode.Fixed)
.onChange((index: number) => {
    this.currentIndex = index;  // 滑动内容时同步更新选中态
})

需要同时处理点击页签切换内容,以及滑动内容同步更新页签选中态,两种交互都要实现才能保证体验一致。

构建自定义底部导航主界面

完成自定义 TabBar 后,构建应用主界面的完整步骤:

  1. 设置 barPosition = BarPosition.End,让 TabBar 显示在底部,设置 controller 为创建好的 TabsController

  2. Tabs 内添加多个 TabContent,分别对应首页、设置页等不同页面。

  3. 给每个 TabContent 设置自定义的 tabBuilder 属性。

  4. 配置 barWidth = '100%'barHeight = 56vpbarMode = BarMode.Fixed 让页签平分宽度。

  5. 给 Tabs 添加 onChange 事件,页签切换后触发,实现滑动内容区时同步更新页签选中样式。

总结

本节课学习了 Tabs 页签组件的核心知识:

  1. 组件定义与组成:Tabs 是通过页签进行内容视图切换的容器组件,由 TabContent(内容区)和 TabBar(导航栏)两部分组成。

  2. 接口与属性barPosition 控制页签位置,index 控制初始页签,controller 控制切换;vertical 控制排列方向,barMode 控制布局模式(Fixed 平均分配/Scrollable 滑动浏览)。

  3. 布局配置:顶部导航(Start + false)、底部导航(End + false)、侧边导航(Start + true)。

  4. 结构规则:Tabs 父容器包裹多个 TabContent 子组件,每个 TabContent 通过 .tabBar() 配置页签内容。TabContent 不支持独立设置宽高。

  5. 自定义 TabBar:通过 @Builder 装饰器自定义样式,使用状态变量控制选中态,通过 TabsController 控制切换,通过 onChange 同步滑动与点击交互。

Logo

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

更多推荐