#跟着若城学鸿蒙# ArkUI 标签页组件(Tabs & TabContent)全指南
·
1. 核心概念
标签页(Tabs)是一种常见的多视图切换方案:用户通过点击不同的页签(TabBar)来切换对应内容区(TabContent)。ArkUI 通过 Tabs + TabContent 组件对这一场景进行了封装:
- **
Tabs**:外层容器,负责布局与状态管理; - **
TabContent**:子组件,只能在Tabs内出现,每个实例对应一个页签及其视图;
2. 快速上手
下面示例展示了一个最简版的上下排列标签页:
@Entry @Component
struct SimpleTabsDemo {
private controller = new TabsController();
build() {
Tabs({
barPosition: BarPosition.Start, // 页签在顶部
controller: this.controller
}) {
// — 第一个标签页 —
TabContent() {
Column({ alignItems: HorizontalAlign.Center, justifyContent: FlexAlign.Center }) {
Text("首页内容").fontSize(24);
}
}
.tabBar("首页")
// — 第二个标签页 —
TabContent() {
Column({ alignItems: HorizontalAlign.Center, justifyContent: FlexAlign.Center }) {
Text("设置内容").fontSize(24);
}
}
.tabBar("设置")
}
.width("100%")
.height("100%");
}
}
barPosition: BarPosition.Start:顶部水平排列;controller:可以在外部通过controller.changeIndex()动态切换;.tabBar("文本"):为每个TabContent指定页签标题。
3. Tabs 常用属性
| 方法 | 说明 |
|---|---|
.vertical(true/false) |
是否左右排列页签(true 左右,false 上下) |
.scrollable(true/false) |
是否允许手势滑动切换内容(默认 true) |
.barMode(BarMode.Fixed) |
页签宽度分配,Fixed 平均分配 / Scrollable 根据内容自适应 |
.barWidth(length) |
竖排时页签栏宽度 |
.barHeight(length) |
横排时页签栏高度 |
.animationDuration(ms) |
切换动画时长,单位毫秒 |
.onChange((idx) => {...}) |
页签切换回调,idx 当前激活页签下标 |
4. 布局示例
4.1 横向固定平均分配
Tabs({ barPosition: BarPosition.End }) // 底部水平排列
.barMode(BarMode.Fixed)
.barHeight(50)
.onChange((idx) => console.log("当前页签:", idx))
4.2 纵向可滑动自适应
Tabs({ barPosition: BarPosition.Start })
.vertical(true) // 左侧竖排
.scrollable(true)
.barMode(BarMode.Scrollable)
.barWidth(80)
5. 自定义 TabContent 标签
除了简单的文本或图标,你还可以传入一个自定义的构建器:
@Entry @Component
struct CustomTabsDemo {
private ctrl = new TabsController();
@State idx = 0;
@Builder tabItem(label: string, icon: string, selected: boolean) {
Column({ alignItems: HorizontalAlign.Center, justifyContent: FlexAlign.Center }) {
Image(selected ? $r("app.media."+icon+"_sel") : $r("app.media."+icon))
.size({ width: 24, height: 24 });
Text(label).fontSize(14)
.fontColor(selected ? "#007AFF" : "#666");
}
.width(100.percent)
.height(100.percent)
.onClick(() => {
this.idx = label === "消息" ? 0 : 1;
this.ctrl.changeIndex(this.idx);
});
}
build() {
Tabs({ controller: this.ctrl })
.barMode(BarMode.Fixed)
.onChange(index => this.idx = index) {
TabContent()
.tabBar(() => this.tabItem("消息", "icon_msg", this.idx === 0)) {
/* ...内容... */
}
TabContent()
.tabBar(() => this.tabItem("好友", "icon_friends", this.idx === 1)) {
/* ...内容... */
}
}
}
}
6. 完整示例
@Entry @Component
struct FullTabsExample {
private controller = new TabsController();
@State activeIndex = 0;
build() {
Column({ space: 0 }) {
// — 标签页容器 —
Tabs({
barPosition: BarPosition.Start,
controller: this.controller
})
.barMode(BarMode.Scrollable)
.barHeight(48)
.animationDuration(300)
.onChange(idx => this.activeIndex = idx) {
["消息", "联系人", "动态"].map((label, i) =>
TabContent()
.tabBar(label)
)
}
// — 底部内容展示 —
Box({ flex: 1, backgroundColor: ["#aabbcc","#bbccaa","#ccaabb"][this.activeIndex] }) {
Text(`当前: ${["消息","联系人","动态"][this.activeIndex]}`)
.fontSize(20)
.textAlign(TextAlign.Center)
.padding(20);
}
}
.width("100%")
.height("100%");
}
}
7. 小贴士
-
性能优化:
- 当页签数量较多时,开启
.scrollable(true)并设置合理barWidth,避免全部均匀分配导致过小。
- 当页签数量较多时,开启
-
动画体验:
animationDuration可调节切换动画时长,配合TabsController.changeIndex()可实现编程式切换。
-
可访问性:
- 为自定义标签添加无障碍描述(
accessibilityLabel),确保屏幕阅读器友好。
- 为自定义标签添加无障碍描述(
通过以上用法,你可以在 ArkUI 中灵活配置“上下”/“左右”、可滑动/不可滑动、平均分配/自适应等任意组合,快速搭建符合业务需求的多视图切换组件。
祝你编码愉快!
更多推荐

所有评论(0)