鸿蒙HarmonyOS开发:tabs结合tabContent实现底部tabBar导航栏页面布局

文章目录

一、组件介绍

Tabs组件的页面组成包含两个部分,分别是TabContent和TabBar。TabContent是内容页,TabBar是导航页签栏,页面结构如下图所示,根据不同的导航类型,布局会有区别,可以分为底部导航、顶部导航、侧边导航,其导航栏分别位于底部、顶部和侧边。

1、Tabs

通过页签进行内容视图切换的容器组件,每个页签对应一个内容视图。

仅可包含子组件TabContent。

复制代码
Tabs(value?: {barPosition?: BarPosition, index?: number, controller?: TabsController})
参数
参数名 参数类型 必填 参数描述
barPosition BarPosition 设置Tabs的页签位置。 默认值:BarPosition.Start
index number 设置当前显示页签的索引。 默认值:0 说明: 设置为小于0的值时按默认值显示。 可选值为[0, TabContent子节点数量-1]。 设置不同值时,默认生效切换动效,可以设置animationDuration为0关闭动画。
controller TabsController 设置Tabs控制器。
属性
名称 参数类型 描述
vertical boolean 设置为false是为横向Tabs,设置为true时为纵向Tabs。 默认值:false
scrollable boolean 设置为true时可以通过滑动页面进行页面切换,为false时不可滑动切换页面。 默认值:true
barMode BarMode TabBar布局模式,具体描述见BarMode枚举说明。 默认值:BarMode.Fixed
barWidth number TabBar的宽度值。
barHeight number TabBar的高度值。
animationDuration number 点击TabBar页签切换TabContent的动画时长。不设置时,点击TabBar页签切换TabContent无动画。 默认值:300 说明: 该参数不支持百分比设置;设置为小于0时,按默认值300ms显示。
事件
复制代码
onChange(event: (index: number) => void)

Tab页签切换后触发的事件。

  • index:当前显示的index索引,索引从0开始计算。

触发该事件的条件:

  • 1、TabContent支持滑动时,组件触发滑动时触发。
  • 2、通过控制器API接口调用。
  • 3、通过状态变量构造的属性值进行修改。
  • 4、通过页签处点击触发。
TabsController

Tabs组件的控制器,用于控制Tabs组件进行页签切换。不支持一个TabsController控制多个Tabs组件。

复制代码
controller: TabsController = new TabsController()
changeIndex(value: number): void

参数:

参数名 参数类型 必填 参数描述
value number 页签在Tabs里的索引值,索引值从0开始。 说明: 设置小于0或大于最大数量的值时,该事件失效。
2、子组件
复制代码
TabContent()
属性
名称 参数类型 描述
tabBar string Resource
说明
  • TabContent组件不支持设置通用宽度属性,其宽度默认撑满Tabs父组件。
  • TabContent组件不支持设置通用高度属性,其高度由Tabs父组件高度与TabBar组件高度决定。
  • vertical属性为false值,交换上述2个限制。
  • TabContent组件不支持内容过长时页面的滑动,如需页面滑动,可嵌套List使用。

二、基础示例

1、基础顶部导航
复制代码
@Entry
@Component
struct TabsPage2 {
  build() {
    Column() {
      Tabs() {
        TabContent() {
          Text('首页的内容').fontSize(30)
        }
        .tabBar('首页')

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

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

        TabContent() {
          Text('我的内容').fontSize(30)
        }
        .tabBar("我的")
      }
    }
    .width('100%')
    .height('100%')
  }
}
2、效果
3、可以滚动导航栏

滚动导航栏可以用于顶部导航栏或者侧边导航栏的设置,内容分类较多,屏幕宽度无法容纳所有分类页签的情况下,需要使用可滚动的导航栏,支持用户点击和滑动来加载隐藏的页签内容。

滚动导航栏需要设置Tabs组件的barMode属性,默认情况下其值为Fixed,表示为固定导航栏,设置为Scrollable即可设置为可滚动导航栏。

复制代码
@Entry
@Component
struct TabsPage2 {
  @State tabsList: Array<string> = ['关注', '视频', '游戏', '数码', '科技', '体育', '影视', '人文', '艺术', '自然', '军事'];

  build() {
    Column() {
      Tabs() {
        ForEach(this.tabsList, (item) => {
          TabContent() {
            Text(item).fontSize(30)
          }
          .tabBar(item)
        })
      }.barMode(BarMode.Scrollable)
    }
    .width('100%')
    .height('100%')
  }
}
2、效果

三、扩展示例

自定义导航栏

对于底部导航栏,一般作为应用主页面功能区分,为了更好的用户体验,会组合文字以及对应语义图标表示页签内容,这种情况下,需要自定义导航页签的样式。

系统默认情况下采用了下划线标志当前活跃的页签,而自定义导航栏需要自行实现相应的样式,用于区分当前活跃页签和未活跃页签。设置自定义导航栏需要使用tabBar的参数,以其支持的CustomBuilder的方式传入自定义的函数组件样式。例如这里声明TabBuilder的自定义函数组件,传入参数包括页签文字title,对应位置index,以及选中状态和未选中状态的图片资源。通过当前活跃的currentIndex和页签对应的targetIndex匹配与否,决定UI显示的样式。

  • 在TabContent对应tabBar属性中传入自定义函数组件,并传递相应的参数。

  • 在不使用自定义导航栏时,系统默认的Tabs会实现切换逻辑。在使用了自定义导航栏后,切换页签的逻辑需要手动实现。即用户点击对应页签时,屏幕需要显示相应的内容页 。

  • 切换指定页签需要使用TabsController,TabsController是Tabs组件的控制器,用于控制Tabs组件进行页签切换。通过TabsController的changeIndex方法来实现跳转至指定索引值对应的TabContent内容。

  • 使用自定义导航栏时,在tabBar属性中传入对应的@Builder,并传入相应的参数。

1、代码

tabsPage.ets

复制代码
import {Cate} from "./tabs/cate"
import {Cart} from "./tabs/cart"
import {Msg} from "./tabs/msg"
import {User} from "./tabs/user"

@Entry
@Component
struct TabsPage {

  @State currentIndex: number = 0

  private tabsController: TabsController = new TabsController()

  @Builder TabBuilder(title:string,targetIndex:number,normalImg:Resource,selectedImg:Resource){
    Column(){
      Image(this.currentIndex==targetIndex?selectedImg:normalImg)
        .width(28)
        .height(28)
      Text(title)
        .fontSize(14)
        .margin({top:4})
        .fontColor(this.currentIndex==targetIndex?'#45C461':'#999999')
    }
    .backgroundColor("#ffffff")
    .width('100%')
    .height(60)
    .justifyContent(FlexAlign.Center)
    .onClick(()=>{
      this.currentIndex=targetIndex
      this.tabsController.changeIndex(this.currentIndex)
    })
  }

  build() {
    Column() {
      Tabs({barPosition:BarPosition.End,controller:this.tabsController,index:0}){
        TabContent(){
          Cate()
        }.tabBar(this.TabBuilder('分类',0,$r("app.media.tabs_1_off"),$r("app.media.tabs_1_on")))
        TabContent(){
          Cart()
        }.tabBar(this.TabBuilder('购物车',1,$r("app.media.tabs_2_off"),$r("app.media.tabs_2_on")))
        TabContent(){
          Msg()
        }.tabBar(this.TabBuilder('消息',2,$r("app.media.tabs_3_off"),$r("app.media.tabs_3_on")))
        TabContent(){
          User()
        }.tabBar(this.TabBuilder('我的',3,$r("app.media.tabs_4_off"),$r("app.media.tabs_4_on")))
      }
      .scrollable(false)//去掉左右滑动的效果
      .animationDuration(0)//去掉左右滑动的动画
    }
    .backgroundColor("#eeeeee")
    .width('100%')
    .height('100%')
  }
}

tabs/cart.ets

复制代码
@Component

export struct Cart {
  build(){
    Text("购物车")
  }
}

其他页面内容都一样,自行编写。

2、效果
相关推荐
前端菜鸟日常11 小时前
鸿蒙Arkts开发飞机大战小游戏,包含无敌模式,自动射弹,暂停和继续
华为·harmonyos
HMS Core12 小时前
【FAQ】HarmonyOS SDK 闭源开放能力 —Account Kit(3)
华为·harmonyos
前端菜鸟日常1 天前
鸿蒙版(ArkTs) 贪吃蛇,包含无敌模式 最高分 暂停和继续功能
华为·harmonyos
鸿蒙布道师1 天前
鸿蒙NEXT开发数值工具类(TS)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
塞尔维亚大汉2 天前
鸿蒙南向开发 ——轻量系统芯片移植指南(二)
物联网·嵌入式·harmonyos
别说我什么都不会2 天前
OpenHarmony内核系统调用hats测试用例编写指南
物联网·嵌入式·harmonyos
90后的晨仔2 天前
鸿蒙ArkTS是如何实现并发的?
harmonyos
鸿蒙布道师2 天前
鸿蒙NEXT开发日期工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
HMSCore2 天前
在应用内购票、寄件时,如何一键填充所需信息?
harmonyos
HarmonyOS_SDK2 天前
在应用内购票、寄件时,如何一键填充所需信息?
harmonyos