HarmonyOS 6.1 实战:Tabs 标签页布局全面解析

发布时间:2026/7/22 23:17:38
HarmonyOS 6.1 实战:Tabs 标签页布局全面解析 前言Tabs是 ArkUI 中实现标签页底部导航、顶部分类导航的专用组件内置切换动画和TabContent懒加载开发者只需定义TabBar和对应内容。本文演示从基础用法到自定义 TabBar 样式的完整实现。运行效果初始状态底部导航第一页切换到第三页核心 API 一览API说明Tabs({ barPosition, index, controller? })标签页容器TabContent()每个标签页的内容区域.tabBar(string/CustomBuilder/TabBarStyle)标签页头支持文字、自定义组件.barPosition(BarPosition)标签栏位置Start顶部/ End底部.scrollable(bool)标签栏是否可横向滚动.animationDuration(ms)内容切换动画时长0 表示禁用.onChange(idx)页签切换回调TabsController.changeIndex(n)编程式切换标签页完整示例代码interface ArticleItem { title: string time: string category: string } Entry Component struct Index { State currentTab: number 0 State innerTab: number 0 private controller: TabsController new TabsController() private navItems: string[] [ 首页, 资讯, 组件] private navIcons: string[] [, , , ] private subTabs: string[] [推荐, 热门, 最新] private sampleArticles: ArticleItem[] [ { title: HarmonyOS 6.1 正式发布带来 200 新特性, time: 2分钟前, category: 推荐 }, { title: ArkUI 组件完整教程从入门到实战, time: 15分钟前, category: 推荐 }, { title: 折叠屏开发指南双栏布局最佳实践, time: 1小时前, category: 热门 }, { title: 鸿蒙应用性能优化渲染帧率提升 40%, time: 2小时前, category: 热门 }, { title: RelativeContainer 高级布局技巧详解, time: 3小时前, category: 最新 }, { title: Navigation 组件完全指南路由与传参, time: 昨天, category: 最新 }, ] Builder tabBarItem(icon: string, label: string, idx: number) { Column({ space: 4 }) { Text(icon).fontSize(22) Text(label.replace(/^[^\s] /, )) .fontSize(10) .fontColor(this.currentTab idx ? #0066ff : #888888) .fontWeight(this.currentTab idx ? FontWeight.Bold : FontWeight.Normal) } .width(100%) .height(100%) .justifyContent(FlexAlign.Center) .alignItems(HorizontalAlign.Center) .backgroundColor(this.currentTab idx ? #f0f5ff : #ffffff) } Builder articleCard(item: ArticleItem) { Column({ space: 6 }) { Text(item.title) .fontSize(15) .fontColor(#1a1a1a) .fontWeight(FontWeight.Medium) .maxLines(2) .textOverflow({ overflow: TextOverflow.Ellipsis }) Row({ space: 8 }) { Text(item.category) .fontSize(11) .fontColor(#0066ff) .backgroundColor(#f0f5ff) .padding({ left: 6, right: 6, top: 2, bottom: 2 }) .borderRadius(4) Text(item.time) .fontSize(11) .fontColor(#aaa) } } .width(100%) .padding({ left: 16, right: 16, top: 14, bottom: 14 }) .backgroundColor(#ffffff) .border({ width: { bottom: 1 }, color: #f5f5f5 }) .alignItems(HorizontalAlign.Start) } build() { // 外层底部导航 Tabs Tabs({ barPosition: BarPosition.End, index: this.currentTab, controller: this.controller }) { // ── Tab 1: 首页 ── TabContent() { Column() { // 嵌套 Tabs顶部分类导航 Tabs({ barPosition: BarPosition.Start, index: this.innerTab }) { ForEach(this.subTabs, (tab: string, tabIdx: number) { TabContent() { List() { ForEach(this.sampleArticles, (article: ArticleItem) { ListItem() { this.articleCard(article) } }) } .width(100%) .height(100%) .backgroundColor(#f8f8f8) } .tabBar( Column() { Text(tab) .fontSize(14) .fontColor(this.innerTab tabIdx ? #0066ff : #555) .fontWeight(this.innerTab tabIdx ? FontWeight.Bold : FontWeight.Normal) .height(40) Column() .width(this.innerTab tabIdx ? 24 : 0) .height(2) .backgroundColor(#0066ff) .borderRadius(1) } .height(44) .justifyContent(FlexAlign.Center) ) }) } .scrollable(false) .animationDuration(200) .onChange((idx: number) { this.innerTab idx }) .layoutWeight(1) } .width(100%) .height(100%) } .tabBar(this.tabBarItem(, 首页, 0)) // ── Tab 2: 资讯 ── TabContent() { Column({ space: 16 }) { Text( 资讯中心) .fontSize(20) .fontWeight(FontWeight.Bold) .padding({ top: 32, left: 16 }) Text(暂无新资讯敬请期待) .fontSize(14) .fontColor(#aaa) } .width(100%) .height(100%) .alignItems(HorizontalAlign.Start) } .tabBar(this.tabBarItem(, 资讯, 1)) // ── Tab 3: 组件 ── TabContent() { Column({ space: 16 }) { Text( 组件中心) .fontSize(20) .fontWeight(FontWeight.Bold) .padding({ top: 32, left: 16 }) Text(200 ArkUI 内置组件持续更新中) .fontSize(14) .fontColor(#aaa) .padding({ left: 16 }) } .width(100%) .height(100%) .alignItems(HorizontalAlign.Start) } .tabBar(this.tabBarItem(, 组件, 2)) } .scrollable(false) .animationDuration(300) .onChange((idx: number) { this.currentTab idx }) .width(100%) .height(100%) .backgroundColor(#f8f8f8) } }关键知识点1. barPosition标签栏位置Tabs({ barPosition: BarPosition.End }) // 底部移动应用底部导航 Tabs({ barPosition: BarPosition.Start }) // 顶部内容分类导航2. tabBar 的三种写法// 方式 1字符串最简单只有文字 TabContent() { ... }.tabBar(首页) // 方式 2Builder 引用自定义图标 文字 TabContent() { ... }.tabBar(this.myTabBarBuilder) // 方式 3SubTabBarStyle / BottomTabBarStyle 内置样式 TabContent() { ... }.tabBar(new SubTabBarStyle(首页)) TabContent() { ... }.tabBar(new BottomTabBarStyle($r(app.media.home), 首页))3. 嵌套 TabsTabs 支持嵌套使用外层做底部导航内层做顶部分类切换。注意两层的currentTab状态要分开管理State outerTab: number 0 // 外层底部导航 State innerTab: number 0 // 内层顶部分类4. animationDuration.animationDuration(300) // 300ms 滑动动画默认 .animationDuration(0) // 禁用动画立即切换内容区域的切换动画时长不影响 tabBar 本身的高亮状态更新速度。5. scrollable 标签栏滚动当标签页很多时设置.scrollable(true)让 tabBar 可以横向滚动避免标签文字被压缩Tabs() .scrollable(true) // tabBar 超出宽度时可横向滚动6. TabsController 编程式切换private controller: TabsController new TabsController() Tabs({ controller: this.controller }) { ... } // 跳转到第 2 个 Tab下标 1 this.controller.changeIndex(1)小结Tabs专为标签页场景设计比手写Column if/else切换更规范、有内置动画barPosition.End做底部导航barPosition.Start做顶部分类可嵌套使用tabBar支持字符串、Builder、内置 Style 三种方式自定义程度依次增加当选中状态高亮颜色、指示器依赖State currentTab必须在onChange中同步更新多层嵌套时每层的currentTab状态需独立维护避免相互干扰