#跟着若城学鸿蒙# Tabs 组件使用指南
·
在多标签页场景下,ArkUI 提供了 Tabs
与 TabContent
两个组件,帮助你快速实现不同内容区的切换展示。每个标签对应一个 TabContent
子组件,Tabs
负责整体容器的布局与交互。
一、基础用法
@Entry @Component
struct SimpleTabsDemo {
private controller: TabsController = new TabsController();
build() {
Column({ space: 0 }) {
// 1. 定义 Tabs 容器,barPosition 决定标签栏方向
Tabs({
barPosition: BarPosition.Start, // 标签栏顶端
controller: this.controller, // 控制器,用于编程式切换
index: 0 // 默认激活第一个标签
})
.size({ width: "100%", height: "100%" })
.vertical(false) // 上下排列(默认)
{
// 2. 每个 TabContent 对应一个内容视图
TabContent()
.tabBar("消息") // 文本标签
{
Column({ alignItems: HorizontalAlign.Center }) {
Text("这里是消息页面")
.fontSize(24)
.padding(20)
}
}
TabContent()
.tabBar({ icon: "icon_contacts", text: "联系人" }) // 图文标签
{
Column({ alignItems: HorizontalAlign.Center }) {
Text("这里是联系人页面")
.fontSize(24)
.padding(20)
}
}
TabContent()
.tabBar("动态")
{
Column({ alignItems: HorizontalAlign.Center }) {
Text("这里是动态页面")
.fontSize(24)
.padding(20)
}
}
}
}
}
}
barPosition: BarPosition.Start
:标签在上方;vertical(false)
:上下排列标签页;- 每个
TabContent().tabBar(...) { ... }
定义一个标签与对应内容。
二、左右布局与底部布局
-
左右排列(
vertical(true)
)
标签栏在左右侧,适合复杂侧边导航。 -
底部排列(
barPosition: BarPosition.End
+vertical(false)
)
标签栏在底部,典型的移动端导航结构。
Tabs({ barPosition: BarPosition.End, controller: this.controller })
.vertical(false) // 底部标签
.barHeight(60) // 指定高度
.barMode(BarMode.Fixed) // 标签均分
.onChange(idx => { /* 切换回调 */ })
三、常用属性
方法 | 说明 |
---|---|
vertical(bool) |
是否左右布局,true 左右,false 上下(默认) |
barPosition(BarPosition) |
标签栏位置:Start (上/左)、End (下/右) |
scrollable(bool) |
标签栏是否可滑动,超出宽度时横向滚动(默认 true ) |
barMode(BarMode) |
Fixed (均分宽度)、Scrollable (实际宽度) |
barWidth(length) |
标签栏宽度(左右布局时生效) |
barHeight(length) |
标签栏高度(上下布局时生效) |
animationDuration(ms) |
切换内容的动画时长,毫秒单位,默认 200 |
onChange((index)⇒void) |
用户切换标签的回调,返回当前标签索引 |
四、编程式切换
通过传入统一的 TabsController
,可以在外部调用切换:
// 切换到第二个标签
this.controller.changeIndex(1);
也可在自定义标签中直接触发:
TabContent()
.tabBar(customBuilder)
.onClick(() => {
this.controller.changeIndex(2);
})
五、自定义标签样式
TabContent.tabBar(...)
支持以下形式:
- 纯文本:
.tabBar("标签名称")
- 图文对象:
.tabBar({ icon: "资源ID", text: "名称" })
- 自定义 Builder:提供 JSX/DSL 构建函数,完全自定义渲染。
例如,结合 @Builder
构造圆形图标加文字的标签:
@Builder tabItem(iconRes: string, label: string, active: boolean) {
Column({ alignItems: HorizontalAlign.Center, space: 4 }) {
Image(iconRes)
.size({ width: 24, height: 24 })
.opacity(active ? 1 : 0.6);
Text(label)
.fontSize(14)
.fontColor(active ? "#2a58d0" : "#888");
}
.onClick(() => this.controller.changeIndex( indexOf(label) ));
}
六、完整示例
@Entry @Component
struct TabsFullDemo {
@State currentIndex: number = 0;
private ctrl: TabsController = new TabsController();
build() {
Column() {
Tabs({
barPosition: BarPosition.End,
controller: this.ctrl,
index: this.currentIndex
})
.barHeight(56)
.barMode(BarMode.Scrollable)
.onChange(idx => this.currentIndex = idx)
.vertical(false)
{
TabContent()
.tabBar(this.tabBuilder("消息", 0)) {
Text("消息页内容").fontSize(20).padding(16);
}
TabContent()
.tabBar(this.tabBuilder("联系人", 1)) {
Text("联系人页内容").fontSize(20).padding(16);
}
TabContent()
.tabBar(this.tabBuilder("动态", 2)) {
Text("动态页内容").fontSize(20).padding(16);
}
}
}
}
@Builder
private tabBuilder(label: string, idx: number) {
let active = (idx === this.currentIndex);
Column({ alignItems: HorizontalAlign.Center, space: 4 }) {
Image(active ? "icon_sel" : "icon_nor")
.size({ width: 20, height: 20 });
Text(label)
.fontSize(14)
.fontColor(active ? "#2a58d0" : "#666");
}
.onClick(() => {
this.currentIndex = idx;
this.ctrl.changeIndex(idx);
})
}
}
这样,你便拥有了一个功能齐全、可编程、易于自定义的多标签切换组件。无论是移动端底栏导航,还是桌面端侧边标签页,都能一行代码完成布局与交互。
更多推荐
所有评论(0)