TabBar的布局效果可以根据不同的设计需求来实现多种样式。以下是一些常见的TabBar布局效果:
本文将基于上述场景,逐一阐述其具体实现方式。
问题场景 | 问题描述 | 解决方案 |
|---|---|---|
场景一 | 实现不同方向的TabBar布局效果。 | 通过barPosition属性和vertical属性,实现TabBar不同方向的布局。 |
场景二 | 实现页签的居中或左右对齐的布局效果。 | 通过barMode可以设置TabBar布局模式,再加上TabsOptions中的barModifier可以设置tabBar的align属性实现页签对齐布局效果。 |
场景三 | 实现TabBar左右分布的布局效果。 | 利用Stack组件自定义TabBar,再使用position属性自定义每一个页签的位置。则可实现页签不均匀分布的效果。 |
场景四 | 实现每个页签宽度均不相同的布局效果。 | 通过将barMode设置为BarMode.Scrollable可滚动模式,tabBar的宽度即可以根据实际宽度显示。 |
场景五 | 实现页签布局根据数量不同,进行动态调整的效果。 | 通过barGridAlign属性可以实现以栅格化方式设置TabBar的可见区域。将barGridAlign属性与页签个数相结合,即可达到动态调整页签布局的效果。 |
可通过barPosition属性设置页签的位置,其取值为BarPosition.Start或BarPosition.End。默认值为BarPosition.Start,表示页签位于页面顶部;设置为End时,页签则显示在页面底部。
此外,vertical属性用于控制页签的布局方向,默认值为false,表示横向布局(页签位于顶部或底部);当设为true时,页签变为纵向布局,显示在屏幕左侧或右侧。
综上所述,可以得出下表结论:
barPosition取值 | vertical取值 | TabBar位置 |
|---|---|---|
BarPosition.Start(默认值) | true | 屏幕左侧 |
BarPosition.Start(默认值) | false(默认值) | 屏幕顶部 |
BarPosition.End | true | 屏幕右侧 |
BarPosition.End | false(默认值) | 屏幕底部 |
用TabBar位于屏幕左侧举例,实现代码如下:
@Entry
@Component
struct TabBarLayoutInDifferentDirections {
build() {
Column() {
Tabs({
barPosition: BarPosition.Start
}) {
TabContent() {
Column() {
Text('首页');
}.width('100%').height('100%')
.justifyContent(FlexAlign.Center);
}.tabBar('首页');
TabContent() {
Column() {
Text('商城');
}.width('100%').height('100%')
.justifyContent(FlexAlign.Center);
}.tabBar('商城');
TabContent() {
Column() {
Text('我的');
}.width('100%').height('100%')
.justifyContent(FlexAlign.Center);
}.tabBar('我的');
}.vertical(true)
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]);
};
}
} 实现效果如下:

通过barMode可以设置TabBar布局模式,再加上TabsOptions中的barModifier可以设置tabBar的align属性实现页签对齐布局效果。
详情可参考示例:页签对齐布局。
在某些应用场景中,开发者可能需要一个自定义的TabBar布局,其中左边的两个页签居左对齐,右边的两个页签居右对齐,而中间部分则可以放置一个图标或按钮。这种布局方式不仅能够有效利用屏幕空间,还能提供更灵活的导航和功能入口,提升用户体验。
利用Stack组件自定义TabBar,再使用position属性自定义每一个页签的位置。则可实现页签不均匀分布的效果。
实现代码如下:
@Entry
@Component
export struct TabBarAlignLeftAndRight {
currentIndex: number = 0;
@State selectedIndex: number = 0;
fontColor: string = '#000';
selectedFontColor: string = '#0A59F7';
tabName: Array<string> = ['首页', '商城', '更多', '我的'];
private controller: TabsController = new TabsController();
@Builder
tabBuilder(index: number, name: string) {
Column() {
Text(name)
.fontColor(this.selectedIndex === index ? this.selectedFontColor : this.fontColor)
.fontSize(16)
.fontWeight(this.selectedIndex === index ? 500 : 400)
.lineHeight(22)
.margin({ top: 17, bottom: 7 });
}
.onClick(() => {
this.controller.changeIndex(index);
this.selectedIndex = index;
})
.padding(10)
// 设置TabItem的相对位置
.position(
index === 1 ? { left: 80 } :
index === 2 ? { right: 90 } :
index === 3 ? { right: 0 } : {});
}
build() {
Stack({ alignContent: Alignment.BottomStart }) {
Tabs({
barPosition: BarPosition.End,
index: this.currentIndex,
controller: this.controller
}) {
TabContent() {
Column() {
Text('首页');
}.width('100%').height('100%')
.justifyContent(FlexAlign.Center);
};
TabContent() {
Column() {
Text('商城');
}.width('100%').height('100%')
.justifyContent(FlexAlign.Center);
};
TabContent() {
Column() {
Text('更多');
}.width('100%').height('100%')
.justifyContent(FlexAlign.Center);
};
TabContent() {
Column() {
Text('我的');
}.width('100%').height('100%')
.justifyContent(FlexAlign.Center);
};
}
.barHeight(0)
.onAnimationStart((index: number, targetIndex: number) => {
if (index === targetIndex) {
return;
}
this.selectedIndex = targetIndex;
});
Stack() {
// 用Row组件实现TabBar效果
Row() {
ForEach(this.tabName, (item: string, index: number) => {
this.tabBuilder(index, item);
});
}
.justifyContent(FlexAlign.SpaceBetween)
.alignItems(VerticalAlign.Bottom)
.width('100%')
.backgroundColor(Color.White);
// 开发者按需设计中间宫格展示内容,该示例展示图标
Image($r('app.media.startIcon')) // 资源地址请自行替换
.width(25)
.height(25)
.align(Alignment.Bottom);
};
};
}
} 实现效果如下:

通过将barMode设置为BarMode.Scrollable可滚动模式,tabBar的宽度即可以根据实际宽度显示。
实现代码如下:
@Entry
@Component
struct TabBarLayoutUnevenly {
build() {
Column() {
Tabs() {
TabContent() {
Column() {
Text('首页');
}.width('100%').height('100%')
.justifyContent(FlexAlign.Center);
}.tabBar('首页');
TabContent() {
Column() {
Text('一多适配');
}.width('100%').height('100%')
.justifyContent(FlexAlign.Center);
}.tabBar('一多适配');
TabContent() {
Column() {
Text('HarmonyOS应用');
}.width('100%').height('100%')
.justifyContent(FlexAlign.Center);
}.tabBar('HarmonyOS应用');
TabContent() {
Column() {
Text('实况窗');
}.width('100%').height('100%')
.justifyContent(FlexAlign.Center);
}.tabBar('实况窗');
}.barMode(BarMode.Scrollable);
};
}
} 实现效果如下:

更多实现方式和详情可参考示例:如何给tabBar页签设置不同宽度。
通过barGridAlign属性可以实现以栅格化方式设置TabBar的可见区域。将barGridAlign属性与页签个数相结合,即可达到动态调整页签布局的效果。
详情可参考示例:Tabs如何根据TabBar数量更改页签栏排布和设置TabBar栅格化可见区域。
Q:为什么当barHeight与SubTabBarStyle.of同时设置的时候,文字会出现被部分覆盖的错误样式?
A:子页签的内边距默认值:{left:8.0vp,right:8.0vp,top:17.0vp,bottom:18.0vp}。SubTabBarStyle存在默认的内边距,使用时可以主动设置下:tabBar(SubTabBarStyle.of('文本').padding(0))。
合作咨询
我们的专家服务团队将竭诚为您提供专业的合作咨询服务
解决方案
精准高效的一站式服务支持,助力开发者商业成功