HarmonyOS鸿蒙tabBar的详细讲解

tabBar的基本使用(默认在顶部)

scss 复制代码
@Entry
@Component
struct Index {
  build() {
     Tabs(){
       TabContent(){
         // TabContent下只能有一个子组件哈
         Text("我是消息中的内容")
       }.tabBar("消息")

       TabContent(){
         // TabContent下只能有一个子组件哈
         Text("我是联系人中的内容")
       }.tabBar("联系人")

       TabContent(){
         // TabContent下只能有一个子组件哈
         Text("我是动态中的内容")
       }.tabBar("动态")
     }
  }
}

通过 barPosition来调整tabBar位置

barPosition:BarPosition.Start 在顶部/左侧

barPosition:BarPosition.End 在底部/右侧

scss 复制代码
@Entry
@Component
struct Index {
  build() {
     // barPosition:BarPosition.Start 在顶部
     // barPosition:BarPosition.End 在顶部
     Tabs({barPosition:BarPosition.End}){
       TabContent(){
         // TabContent下只能有一个子组件哈
         Text("我是消息中的内容")
       }.tabBar("消息")

       TabContent(){
         // TabContent下只能有一个子组件哈
         Text("我是联系人中的内容")
       }.tabBar("联系人")

       TabContent(){
         // TabContent下只能有一个子组件哈
         Text("我是动态中的内容")
       }.tabBar("动态")
     }
  }
}

vertical 调整导航的位置,是水平(true)还是垂直(false)

scss 复制代码
@Entry
@Component
struct Index {
  build() {
     // barPosition:BarPosition.Start 在顶部/左侧
     // barPosition:BarPosition.End 在尾部/右侧

     Tabs({barPosition:BarPosition.End}){
       TabContent(){
         // TabContent下只能有一个子组件哈
         Text("我是消息中的内容")
       }.tabBar("消息")

       TabContent(){
         // TabContent下只能有一个子组件哈
         Text("我是联系人中的内容")
       }.tabBar("联系人")

       TabContent(){
         // TabContent下只能有一个子组件哈
         Text("我是动态中的内容")
       }.tabBar("动态")
     }.vertical(true) // 调整导航的位置,是水平(true)还是垂直(false);
  }
}

scrollable:是否通过手势滑动切换内容

scss 复制代码
@Entry
@Component
struct Index {
  build() {
     // barPosition:BarPosition.Start 在顶部/左侧
     // barPosition:BarPosition.End 在顶部/右侧
     Tabs({barPosition:BarPosition.End}){
       TabContent(){
         // TabContent下只能有一个子组件哈
         Text("我是消息中的内容")
       }.tabBar("消息")

       TabContent(){
         // TabContent下只能有一个子组件哈
         Text("我是联系人中的内容")
       }.tabBar("联系人")

       TabContent(){
         // TabContent下只能有一个子组件哈
         Text("我是动态中的内容")
       }.tabBar("动态")
     }.vertical(false) // 调整导航的位置,是水平(true)还是垂直(false);
      .scrollable(false) // 是否通过手势滑动切换(手指向右向左可以滑动) false不允许;true可以
  }
}

animationDuration:切换动画的时间

scss 复制代码
@Entry
@Component
struct Index {
  build() {
     // barPosition:BarPosition.Start 在顶部/左侧
     // barPosition:BarPosition.End 在顶部/右侧
     //
     Tabs({barPosition:BarPosition.End}){
       TabContent(){
         // TabContent下只能有一个子组件哈
         Text("我是消息中的内容")
       }.tabBar("消息")

       TabContent(){
         // TabContent下只能有一个子组件哈
         Text("我是联系人中的内容")
       }.tabBar("联系人")

       TabContent(){
         // TabContent下只能有一个子组件哈
         Text("我是动态中的内容")
       }.tabBar("动态")
     }.vertical(false) // 调整导航的位置,是水平(true)还是垂直(false);
      .scrollable(false) // 是否通过手势滑动切换(手指向右向左可以滑动) false不允许;true可以
      .animationDuration(300) // 切换动画的时间,毫秒
  }
}

很多时候,特别是新闻类的app;

会有很多的tabBar他们是可以进行滚动切换的。

我们可以通过barMode(BarMode.Scrollable)来进行设置,让它滚动

请看下面的例子

很多Tabs标签的时候可以进行滚动

scss 复制代码
@Entry
@Component
struct Index {
  @State titleArr:string[]=['首页1','首页12','首页13','首页14','首页15','首页16','首页17','首页18','首页19',]
  build() {
     Tabs({barPosition:BarPosition.Start}){
       ForEach(this.titleArr,(item:string, index:number)=>{
           TabContent(){
             // TabContent下只能有一个子组件哈
             Text(`我是${item}中的内容`)
           }.tabBar(item)
       })
     }.vertical(false) // 调整导航的位置,是水平(true)还是垂直(false);
      .scrollable(true) // 是否通过手势滑动切换(手指向右向左可以滑动) false不允许;true可以
      .barMode(BarMode.Scrollable)
  }
}

TabBar相关的事件

onTabBarClick事件是Tab页签点击后触发的事件。
typescript 复制代码
Tabs(){}
  .onTabBarClick((order:number)=>{
     // 多次重新点击也会触发,order表示的是点击的tabBar元素下标
     console.log('你点击了这个tab', order)
   })
onChange事件,Tab页签切换后触发的事件。

语法:onChange(event: (index: number) => void)

满足以下任一条件,即可触发该事件:

1、滑动页面进行页面切换时,组件滑动动画结束后触发。

2、通过控制器调用changeIndex接口,Tab页签切换后触发。

3、动态修改状态变量构造的index属性值,Tab页签切换后触发。

4、点击TabBar页签,Tab页签切换后触发。

特殊说明:

使用自定义页签时,在onChange事件中联动可能会导致滑动页面切换后才执行页签联动,引起自定义页签切换效果延迟。

建议在onAnimationStart中监听并刷新当前索引,以确保动效能够及时触发

更改svg图标的颜色

fillColor(value: ResourceColor) 设置填充颜色,设置后填充颜色会覆盖在图片上。

仅对svg图源生效,设置后会替换svg图片中所有可绘制元素的填充颜色。

如需对png图片进行修改颜色,可以使用colorFilter。

scss 复制代码
Image($r("app.media.图标名称")).width(26).height(26).margin({bottom:20}).fillColor(Color.Red)
Image($r("app.media.图标名称")).width(26).height(26).margin({bottom:20}).fillColor(Color.Pink)

切换实现TabBar高亮效果

实现的思路是:通过onChange事件记录当前点击的是哪一个TabBar

然后通过fillColor属性控制svg图片的颜色,点击的那个TabBar进行变色。

fontColor控制文本的颜色,下面我们就一起来看下

less 复制代码
@Entry
@Component
struct Index {
  @State selectIndex:number = 0
  @State activeTextColor:string = "#f9f"
  @Builder
  customBuilder(title:string,iconUrl:string,index:number){
    Column(){
      // rgba(0,0,0,0.9019607843137255)
      Image($r(iconUrl)).width(20).fillColor(this.selectIndex==index ? this.activeTextColor : '')
      Text(title)
        .fontColor(this.selectIndex==index ? this.activeTextColor : '#000') // 更改文字的颜色,通过下标来更改哈
    }
  }
  build() {
     Tabs({ barPosition:BarPosition.End}){
       TabContent(){
         Text("历史内容")
       }.tabBar(this.customBuilder('历史', 'app.media.history',0))

       TabContent(){
         Text("更多内容")
       }.tabBar(this.customBuilder('更多', 'app.media.more',1))
     }.onChange((index:number)=>{
       // 这个事件是在切换的时候就会被触发,可以得到索引,从下标是0开始
       this.selectIndex = index
       console.log('索引', index)
     })
  }
}

尾声

掘有们,今天周五啦。好好复习一下,参加明天的考试。

相关推荐
lovingsoft2 分钟前
Chrome Lighthouse 详解
前端·chrome
Qlly12 分钟前
全栈工程师怎么接需求?从一句「加个功能」聊到能开发、能验收
前端·后端
马可家的菠萝16 分钟前
你的微信“文件传输助手”,是不是已经成了第二个网盘?
前端·后端·架构
略略略啦17 分钟前
Vibe Coding 基于Spec DD和TDD的实践指南
前端
shmily麻瓜小菜鸡38 分钟前
前端实现图片与PDF文字识别敏感信息打码方案
前端·pdf·状态模式
打工仔折腾 AI43 分钟前
LangChain 工具调用实战:从 Tool 定义到 Agent 执行链路拆解
java·前端·人工智能·后端·python·langchain·ai agent 实战
汉堡大王95271 小时前
单次输出拉到100万Token:拆完 Gemini 4 Argon 的续写协议,才看懂谷歌这7个月在憋什么
前端·人工智能·后端
看浪的路人1 小时前
第9讲:大模型应用监控与可观测性——OpenTelemetry + Prometheus + Grafana 全链路追踪
java·前端·spring
内存过载1 小时前
用表格模拟甘特图:项目排期的土办法
前端·低代码
葡萄城技术团队1 小时前
用 SpreadJS 数据验证实现省市区三级联动
前端