鸿蒙Tabs选项卡布局【华为根技术】

举报
tea_year 发表于 2025/06/30 21:32:44 2025/06/30
【摘要】 Tabs组件可以在一个页面内快速实现视图内容的切换,一方面提升查找信息的效率,另一方面精简用户单次获取到的信息量官方文档(指南)https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-navigation-tabs-V13对子组件的要求不支持自定义组件作为子组件, 仅可包含子组件TabContent, 以...
Tabs组件可以在一个页面内快速实现视图内容的切换,一方面提升查找信息的效率,另一方面精简用户单次获取到的信息量
  1. 官方文档(指南)

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-navigation-tabs-V13
  1. 对子组件的要求

不支持自定义组件作为子组件, 仅可包含子组件TabContent, 以及渲染控制类型if/elseForEach, 并且if/else和ForEach下也仅支持TabContent, 不支持自定义组件。
  1. 基本布局

  • Tabs组件的页面组成包含两个部分,分别是TabContent和TabBar。
  • TabContent是内容页,
  • TabBar是导航页签栏,
  • 根据不同的导航类型,布局会有区别,可以分为底部导航、顶部导航、侧边导航,
Tabs() {
  //1. 首页
  TabContent() {
    Text('首页的内容').fontSize(30)
  }
  .tabBar('首页')

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

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

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

常用属性

//  BarPosition.Start  顶部导航
//  BarPosition.End   底部导航
Tabs({ barPosition: BarPosition.End }) {
  // TabContent的内容:首页、发现、推荐、我的
  ...
}
// .barPosition(BarPosition.End)  // 导航栏的位置
// .barWidth('80%')  //导航栏的宽度
// .barHeight(30)  //导航栏的高度
// .barBackgroundColor(Color.Green)  // 导航栏的背景色
// .vertical(true) //垂直导航
// .scrollable(false) // 控制滑动切换
// .barMode(BarMode.Fixed)  // tabBar固定,不可滚动
// .barMode(BarMode.Scrollable)  //tabBar可以滚动
  • barMode属性
    • 固定导航
    .barMode(BarMode.Fixed)  
      当内容分类较为固定且不具有拓展性时,例如底部导航内容分类一般固定,分类数量一般在3-5个,此时使用固定导航栏。固定导航栏不可滚动,无法被拖拽滚动,内容均分tabBar的宽度。
    • 可滚动导航栏
      .barMode(BarMode.Scrollable)

      设置子页签的样式

            Tabs() {
              TabContent() {
                Text("商品的内容").fontSize(16)
              }
              //给tabBar添加图标
              // .tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), '商品'))
              
              //设置当前子页签的样式
              .tabBar(SubTabBarStyle.of('商品')
                .indicator({
                  color: Color.Red, //下划线颜色
                  height: 5, //下划线高度
                  width: 20, //下划线宽度
                  borderRadius: 2, //下划线圆角半径
                  marginTop: 12 //下划线与文字间距
                })
                .labelStyle({
                  selectedColor: '#f00',  // 子页签选中时的颜色
                  unselectedColor: '#00f' // 子页签未选中时颜色
                })
              )
            }
       

      嵌套的Tabs

      // ----------------------------外层的Tabs
      Tabs() {
        TabContent() {
          Text("商品的内容").fontSize(16)
        }.tabBar("商品")
      
        TabContent() {
      
          // ---------------------嵌套的Tabs
          Tabs() {
            TabContent() {
              Text("图书详情的内容").fontSize(16)
            }.tabBar("图书详情")
      
            TabContent() {
              Text("出版信息的内容").fontSize(16)
            }.tabBar("出版信息")
          }
        
        }.tabBar("详情")
      
        TabContent() {
          // ----------------------------嵌套的Tabs
          Tabs() {
            TabContent() {
              Text("短评的内容").fontSize(16)
            }.tabBar("短评")
      
            TabContent() {
              Text("长评的内容").fontSize(16)
            }.tabBar("长评")
          }
        }.tabBar("评论")
      
        TabContent() {
          Text("推荐的内容").fontSize(16)
        }.tabBar("推荐")
      }

      自定义导航栏

      Tabs控制器

      private controller: TabsController = new TabsController();
      
      ...
      
      Tabs({ barPosition: BarPosition.End, controller: this.controller }) {
          ...
      }
      //监听tabContent的切换
      .onChange((index: number) => {
          
      })
      
      //控制TabContent的切换
      this.controller.changeIndex(index);
      
      

      案例代码

      import { LengthMetrics } from '@kit.ArkUI'
      import { DetailDetail } from '../view/detail/DetailDetail'
      import { ProductDetail } from '../view/detail/ProductDetail'
      
      @Entry
      @Component
      struct Del {
        // TabsController是系统提供的控制器类型
        private controller: TabsController = new TabsController();
        @State arr: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9]
        @State activeIndex: number = 1
        @State navList: string[] = ["商品", "详情", "评论", "推荐"]
      
        build() {
          Column() {
            // 自定义tabBar
            Row() {
              Text("返回")
              Flex({
                justifyContent: FlexAlign.SpaceBetween
              }) {
                ForEach(this.navList, (item: string, index: number) => {
                  Column() {
                    Text(item)
                      .fontColor(this.activeIndex === index ? '#f00' : '#000')
                      .fontSize(this.activeIndex === index ? '20' : '16')
                    Divider()
                      .color('#f00')
                      .width('80%')
                      .visibility(this.activeIndex === index ? Visibility.Visible : Visibility.Hidden)
                  }
                  .onClick(() => {
                    this.activeIndex = index
                    //控制TabContent的切换
                    this.controller.changeIndex(index);
                  })
                }, (item: string) => item)
              }
              .width(200)
      
              // .border({ width: 1, color: '#f00' })
              Text("...")
            }
            .width('100%')
            .height(44)
            .backgroundColor(Color.Orange)
            .justifyContent(FlexAlign.SpaceBetween)
        
            //Tabs
            Tabs({ controller: this.controller }) {
              TabContent() {
                Text("商品的内容").fontSize(20).width('90%').height(100).border({ width: 1, color: '#f00' })
              }
      
              TabContent() {
                Text("详情的内容").fontSize(20).width('90%').height(100).border({ width: 1, color: '#f00' })
              }
      
              TabContent() {
                Text("评论的内容").fontSize(20).width('90%').height(100).border({ width: 1, color: '#f00' })
              }
      
              TabContent() {
                Text("推荐的内容").fontSize(20).width('90%').height(100).border({ width: 1, color: '#f00' })
              }
            }
            .barPosition(BarPosition.Start)
            .vertical(false)
            // .scrollable(false)
            .barMode(BarMode.Fixed)
            // 监听tabContent的切换
            .onChange((index: number) => {
              console.log(index.toString())
              this.activeIndex =  index
            })
          }
        }
      }

      数据信息

      [
        {
          unselectedImg: 'home',
          selectedImg: 'activeHome',
          title: '首页'
        },
        {
          unselectedImg: 'star',
          selectedImg: 'activeStar',
          title: '动态'
        },
       
        {
          unselectedImg: 'message',
          selectedImg: 'activeMessage',
          title: '消息'
        },
        {
          unselectedImg: 'people',
          selectedImg: 'activePeople',
          title: '我的'
        }
      ]

      实战目标

      [
        {
          unselectedImg: 'home',
          selectedImg: 'activeHome',
          title: '首页',
          middleMode: false
        },
        {
          unselectedImg: 'star',
          selectedImg: 'activeStar',
          title: '动态',
          middleMode: false
      
        },
        {
          unselectedImg: 'activePlus',
          selectedImg: 'activePlus',
          title: '',
          middleMode: true
      
        },
        {
          unselectedImg: 'message',
          selectedImg: 'activeMessage',
          title: '消息',
          middleMode: false
      
        },
        {
          unselectedImg: 'people',
          selectedImg: 'activePeople',
          title: '我的',
          middleMode: false
        },
      ]

      总结

       标签页(tabs)是移动端应用中常见的用户界面设计元素,用于在有限的屏幕空间内管理和容纳多个页面或视图。而arkts中提供了tabs组件实现这一功能,我们可以看文档,文档中对tabs的描述是”通过页签进行内容视图切换的容器组件,每个页签对应一个内容视图。“,特别注明,子组件仅可包含子组件TabContent,但是我们可以在TabContent中包含我们自定义组件或者你想要包含的组件,tabs的接口定义是Tabs(value?: {barPosition?: BarPosition, index?: number, controller?: TabsController}),

      这三个参数都是可选参数,barPosition用于设置tabs的页签位置,index用于设置初始页签的索引,controller用于设置tabs的控制器。

      【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
      • 点赞
      • 收藏
      • 关注作者

      评论(0

      0/1000
      抱歉,系统识别当前为高风险访问,暂不支持该操作

      全部回复

      上滑加载中

      设置昵称

      在此一键设置昵称,即可参与社区互动!

      *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

      *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。