1# Tabs 2 3通过页签进行内容视图切换的容器组件,每个页签对应一个内容视图。 4 5> **说明:** 6> 7> 该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 8 9 10## 子组件 11 12仅可包含子组件[TabContent](ts-container-tabcontent.md)。 13 14 15## 接口 16 17Tabs(value?: {barPosition?: BarPosition, index?: number, controller?: [TabsController](#tabscontroller)}) 18 19**参数:** 20 21| 参数名 | 参数类型 | 必填 | 参数描述 | 22| ----------- | --------------------------------- | ---- | ---------------------------------------- | 23| barPosition | [BarPosition](#barposition枚举说明)| 否 | 设置Tabs的页签位置。<br/>默认值:BarPosition.Start | 24| index | number | 否 | 设置初始页签索引。<br/>默认值:0<br/>**说明:** <br/>设置为小于0的值时按默认值显示。<br/>可选值为[0, TabContent子节点数量-1]。<br/>设置不同值时,默认生效切换动效,可以设置animationDuration为0关闭动画。<br />从API version 10开始,该参数支持[$$](../../quick-start/arkts-two-way-sync.md)双向绑定变量。 | 25| controller | [TabsController](#tabscontroller) | 否 | 设置Tabs控制器。 | 26 27## BarPosition枚举说明 28 29| 名称 | 描述 | 30| ----- | ---------------------------------------- | 31| Start | vertical属性方法设置为true时,页签位于容器左侧;vertical属性方法设置为false时,页签位于容器顶部。 | 32| End | vertical属性方法设置为true时,页签位于容器右侧;vertical属性方法设置为false时,页签位于容器底部。 | 33 34 35## 属性 36 37除支持[通用属性](ts-universal-attributes-size.md)外,还支持以下属性: 38 39| 名称 | 参数类型 | 描述 | 40| -------------------------------- | ---------------------------------------- | ---------------------------------------- | 41| vertical | boolean | 设置为false是为横向Tabs,设置为true时为纵向Tabs。<br/>默认值:false | 42| scrollable | boolean | 设置为true时可以通过滑动页面进行页面切换,为false时不可滑动切换页面。<br/>默认值:true | 43| barMode | [BarMode](#barmode枚举说明),[ScrollableBarModeOptions](#scrollablebarmodeoptions10对象说明) | TabBar布局模式,BarMode为必选项,ScrollableBarModeOptions为可选项,具体描述见BarMode枚举说明、ScrollableBarModeOptions对象说明。从API version 10开始,支持ScrollableBarModeOptions参数。其中ScrollableBarModeOptions参数仅Scrollable模式下有效,非必填参数。<br/>默认值:BarMode.Fixed | 44| barWidth | number \| Length<sup>8+</sup> | TabBar的宽度值。<br/>默认值:<br/>未设置带样式的TabBar且vertical属性为false时,默认值为Tabs的宽度。<br/>未设置带样式的TabBar且vertical属性为true时,默认值为56vp。<br/>设置SubTabbarStyle样式且vertical属性为false时,默认值为Tabs的宽度。<br/>设置SubTabbarStyle样式且vertical属性为true时,默认值为56vp。<br/>设置BottomTabbarStyle样式且vertical属性为true时,默认值为96vp。<br/>设置BottomTabbarStyle样式且vertical属性为false时,默认值为Tabs的宽度。<br/>**说明:** <br/>设置为小于0或大于Tabs宽度值时,按默认值显示。 | 45| barHeight | number \| Length<sup>8+</sup> | TabBar的高度值。<br/>默认值:<br/>未设置带样式的TabBar且vertical属性为false时,默认值为56vp。<br/>未设置带样式的TabBar且vertical属性为true时,默认值为Tabs的高度。<br/>设置SubTabbarStyle样式且vertical属性为false时,默认值为56vp。<br/>设置SubTabbarStyle样式且vertical属性为true时,默认值为Tabs的高度。<br/>设置BottomTabbarStyle样式且vertical属性为true时,默认值为Tabs的高度。<br/>设置BottomTabbarStyle样式且vertical属性为false时,默认值为56vp。<br/>**说明:** <br/>设置为小于0或大于Tabs高度值时,按默认值显示。 | 46| animationDuration | number | TabContent滑动动画时长。不设置时,点击切换页签无动画,滑动切换有动画;设置时,点击切换和滑动切换都有动画。<br/>默认值:300 <br/>**说明:** <br/>设置为小于0或百分比时,按默认值显示。 | 47| divider<sup>10+</sup> | [DividerStyle](#dividerstyle10对象说明) \| null | 用于设置区分TabBar和TabContent的分割线样式设置分割线样式,默认不显示分割线。<br/> DividerStyle: 分割线的样式;<br/> null: 不显示分割线。 | 48| fadingEdge<sup>10+</sup> | boolean | 设置页签超过容器宽度时是否渐隐消失。<br />默认值:true | 49| barOverlap<sup>10+</sup> | boolean | 设置TabBar是否背后变模糊并叠加在TabContent之上。<br />默认值:false | 50| barBackgroundColor<sup>10+</sup> | [ResourceColor](ts-types.md#resourcecolor) | 设置TabBar的背景颜色。<br />默认值:透明 | 51| barGridAlign<sup>10+</sup> | [BarGridColumnOptions](#bargridcolumnoptions10对象说明) | 以栅格化方式设置TabBar的可见区域。具体参见BarGridColumnOptions对象。仅水平模式下有效,[不适用于XS、XL和XXL设备](../../ui/arkts-layout-development-grid-layout.md#栅格系统断点)。 | 52 53## DividerStyle<sup>10+</sup>对象说明 54 55| 名称 | 参数类型 | 必填 | 描述 | 56| ----------- | ---------------------------------------- | ---- | ---------------------------------------- | 57| strokeWidth | [Length](ts-types.md#length) | 是 | 分割线的线宽(不支持百分比设置)。 | 58| color | [ResourceColor](ts-types.md#resourcecolor) | 否 | 分割线的颜色。<br/>默认值:#33182431 | 59| startMargin | [Length](ts-types.md#length) | 否 | 分割线与侧边栏顶端的距离(不支持百分比设置)。<br/>默认值:0.0<br/>单位:vp | 60| endMargin | [Length](ts-types.md#length) | 否 | 分割线与侧边栏底端的距离(不支持百分比设置)。<br/>默认值:0.0<br/>单位:vp | 61 62## BarGridColumnOptions<sup>10+</sup>对象说明 63 64| 名称 | 参数类型 | 必填 | 描述 | 65| ----------- | ---------------------------------------- | ---- | ---------------------------------------- | 66| margin | [Dimension](ts-types.md#dimension10) | 否 | 网格模式下的column边距(不支持百分比设置)。<br/>默认值:24.0<br/>单位:vp | 67| gutter | [Dimension](ts-types.md#dimension10) | 否 | 网格模式下的column间隔(不支持百分比设置)。<br/>默认值:24.0<br/>单位:vp | 68| sm | number | 否 | 小屏下,页签占用的columns数量,必须是非负偶数。小屏为大于等于320vp但小于600vp。<br/>默认值为-1,代表页签占用TabBar全部宽度。 | 69| md | number | 否 | 中屏下,页签占用的columns数量,必须是非负偶数。中屏为大于等于600vp但小于800vp。<br/>默认值为-1,代表页签占用TabBar全部宽度。 | 70| lg | number | 否 | 大屏下,页签占用的columns数量,必须是非负偶数。大屏为大于等于840vp但小于1024vp。<br/>默认值为-1,代表页签占用TabBar全部宽度。 | 71 72## ScrollableBarModeOptions<sup>10+</sup>对象说明 73 74| 名称 | 参数类型 | 必填 | 描述 | 75| ----------- | ---------------------------------------- | ---- | ---------------------------------------- | 76| margin | [Dimension](ts-types.md#dimension10) | 否 | Scrollable模式下的TabBar的左右边距(不支持百分比设置)。<br/>默认值:0.0<br/>单位:vp | 77| nonScrollableLayoutStyle | [LayoutStyle](#layoutstyle10枚举说明) | 否 | Scrollable模式下不滚动时的页签排布方式。<br/>默认值:LayoutStyle.ALWAYS_CENTER | 78 79## BarMode枚举说明 80 81| 名称 | 描述 | 82| ---------- | ---------------------------------------- | 83| Scrollable | 每一个TabBar均使用实际布局宽度,超过总长度(横向Tabs的barWidth,纵向Tabs的barHeight)后可滑动。 | 84| Fixed | 所有TabBar平均分配barWidth宽度(纵向时平均分配barHeight高度)。 | 85 86## LayoutStyle<sup>10+</sup>枚举说明 87 88| 名称 | 描述 | 89| ---------- | ---------------------------------------- | 90| ALWAYS_CENTER | 当页签内容超过TabBar宽度时,TabBar可滚动。<br/>当页签内容不超过TabBar宽度时,TabBar不可滚动,页签紧凑居中。| 91| ALWAYS_AVERAGE_SPLITE | 当页签内容超过TabBar宽度时,TabBar可滚动。<br/>当页签内容不超过TabBar宽度时,TabBar不可滚动,且所有页签平均分配TabBar宽度。<br/>仅水平模式下有效,否则视为LayoutStyle.ALWAYS_CENTER。| 92| SPACE_BETWEEN_OR_CENTER | 当页签内容超过TabBar宽度时,TabBar可滚动。<br/>当页签内容不超过TabBar宽度但超过TabBar宽度一半时,TabBar不可滚动,页签紧凑居中。<br/>当页签内容不超过TabBar宽度一半时,TabBar不可滚动,保证页签居中排列在TabBar宽度一半,且间距相同。| 93 94## 事件 95 96除支持[通用事件](ts-universal-events-click.md)外,还支持以下事件: 97 98| 名称 | 功能描述 | 99| ---------------------------------------- | ---------------------------------------- | 100| onChange(event: (index: number) => void) | Tab页签切换后触发的事件。<br>- index:当前显示的index索引,索引从0开始计算。<br/>触发该事件的条件:<br/>1、TabContent支持滑动时,组件触发滑动时触发。<br/>2、通过[控制器](#tabscontroller)API接口调用。<br/>3、通过[状态变量](../../quick-start/arkts-state.md)构造的属性值进行修改。<br/>4、通过页签处点击触发。 | 101| onTabBarClick(event: (index: number) => void)<sup>10+</sup> | Tab页签点击后触发的事件。<br>- index:被点击的index索引,索引从0开始计算。<br/>触发该事件的条件:<br/>通过页签处点击触发。 | 102 103## TabsController 104 105Tabs组件的控制器,用于控制Tabs组件进行页签切换。不支持一个TabsController控制多个Tabs组件。 106 107### 导入对象 108 109```ts 110let controller: TabsController = new TabsController() 111``` 112 113### changeIndex 114 115changeIndex(value: number): void 116 117控制Tabs切换到指定页签。 118 119**参数:** 120 121| 参数名 | 参数类型 | 必填 | 参数描述 | 122| ----- | ------ | ---- | ---------------------------------------- | 123| value | number | 是 | 页签在Tabs里的索引值,索引值从0开始。<br/>**说明:** <br/>设置小于0或大于最大数量的值时,该事件失效。 | 124 125 126## 示例 127 128### 示例1 129 130```ts 131// xxx.ets 132@Entry 133@Component 134struct TabsExample { 135 @State fontColor: string = '#182431' 136 @State selectedFontColor: string = '#007DFF' 137 @State currentIndex: number = 0 138 private controller: TabsController = new TabsController() 139 140 @Builder TabBuilder(index: number, name: string) { 141 Column() { 142 Text(name) 143 .fontColor(this.currentIndex === index ? this.selectedFontColor : this.fontColor) 144 .fontSize(16) 145 .fontWeight(this.currentIndex === index ? 500 : 400) 146 .lineHeight(22) 147 .margin({ top: 17, bottom: 7 }) 148 Divider() 149 .strokeWidth(2) 150 .color('#007DFF') 151 .opacity(this.currentIndex === index ? 1 : 0) 152 }.width('100%') 153 } 154 155 build() { 156 Column() { 157 Tabs({ barPosition: BarPosition.Start, controller: this.controller }) { 158 TabContent() { 159 Column().width('100%').height('100%').backgroundColor('#00CB87') 160 }.tabBar(this.TabBuilder(0, 'green')) 161 162 TabContent() { 163 Column().width('100%').height('100%').backgroundColor('#007DFF') 164 }.tabBar(this.TabBuilder(1, 'blue')) 165 166 TabContent() { 167 Column().width('100%').height('100%').backgroundColor('#FFBF00') 168 }.tabBar(this.TabBuilder(2, 'yellow')) 169 170 TabContent() { 171 Column().width('100%').height('100%').backgroundColor('#E67C92') 172 }.tabBar(this.TabBuilder(3, 'pink')) 173 } 174 .vertical(false) 175 .barMode(BarMode.Fixed) 176 .barWidth(360) 177 .barHeight(56) 178 .animationDuration(400) 179 .onChange((index: number) => { 180 this.currentIndex = index 181 }) 182 .width(360) 183 .height(296) 184 .margin({ top: 52 }) 185 .backgroundColor('#F1F3F5') 186 }.width('100%') 187 } 188} 189``` 190 191 192 193### 示例2 194 195```ts 196// xxx.ets 197@Entry 198@Component 199struct TabsDivider1 { 200 private controller1: TabsController = new TabsController() 201 @State dividerColor: string = 'red' 202 @State strokeWidth: number = 2 203 @State startMargin: number = 0 204 @State endMargin: number = 0 205 @State nullFlag: boolean = false 206 207 build() { 208 Column() { 209 Tabs({ controller: this.controller1 }) { 210 TabContent() { 211 Column().width('100%').height('100%').backgroundColor(Color.Pink) 212 }.tabBar('pink') 213 214 TabContent() { 215 Column().width('100%').height('100%').backgroundColor(Color.Yellow) 216 }.tabBar('yellow') 217 218 TabContent() { 219 Column().width('100%').height('100%').backgroundColor(Color.Blue) 220 }.tabBar('blue') 221 222 TabContent() { 223 Column().width('100%').height('100%').backgroundColor(Color.Green) 224 }.tabBar('green') 225 226 TabContent() { 227 Column().width('100%').height('100%').backgroundColor(Color.Red) 228 }.tabBar('red') 229 } 230 .vertical(true) 231 .scrollable(true) 232 .barMode(BarMode.Fixed) 233 .barWidth(70) 234 .barHeight(200) 235 .animationDuration(400) 236 .onChange((index: number) => { 237 console.info(index.toString()) 238 }) 239 .height('200vp') 240 .margin({ bottom: '12vp' }) 241 .divider(this.nullFlag ? null : { 242 strokeWidth: this.strokeWidth, 243 color: this.dividerColor, 244 startMargin: this.startMargin, 245 endMargin: this.endMargin 246 }) 247 248 Button('常规Divider').width('100%').margin({ bottom: '12vp' }) 249 .onClick(() => { 250 this.nullFlag = false; 251 this.strokeWidth = 2; 252 this.dividerColor = 'red'; 253 this.startMargin = 0; 254 this.endMargin = 0; 255 }) 256 Button('空Divider').width('100%').margin({ bottom: '12vp' }) 257 .onClick(() => { 258 this.nullFlag = true 259 }) 260 Button('颜色变为蓝色').width('100%').margin({ bottom: '12vp' }) 261 .onClick(() => { 262 this.dividerColor = 'blue' 263 }) 264 Button('宽度增加').width('100%').margin({ bottom: '12vp' }) 265 .onClick(() => { 266 this.strokeWidth += 2 267 }) 268 Button('宽度减小').width('100%').margin({ bottom: '12vp' }) 269 .onClick(() => { 270 if (this.strokeWidth > 2) { 271 this.strokeWidth -= 2 272 } 273 }) 274 Button('上边距增加').width('100%').margin({ bottom: '12vp' }) 275 .onClick(() => { 276 this.startMargin += 2 277 }) 278 Button('上边距减少').width('100%').margin({ bottom: '12vp' }) 279 .onClick(() => { 280 if (this.startMargin > 2) { 281 this.startMargin -= 2 282 } 283 }) 284 Button('下边距增加').width('100%').margin({ bottom: '12vp' }) 285 .onClick(() => { 286 this.endMargin += 2 287 }) 288 Button('下边距减少').width('100%').margin({ bottom: '12vp' }) 289 .onClick(() => { 290 if (this.endMargin > 2) { 291 this.endMargin -= 2 292 } 293 }) 294 }.padding({ top: '24vp', left: '24vp', right: '24vp' }) 295 } 296} 297``` 298 299 300 301### 示例3 302 303```ts 304// xxx.ets 305@Entry 306@Component 307struct TabsOpaque { 308 @State message: string = 'Hello World' 309 private controller: TabsController = new TabsController() 310 private controller1: TabsController = new TabsController() 311 @State selfFadingFade: boolean = true; 312 313 build() { 314 Column() { 315 Button('子页签设置渐隐').width('100%').margin({ bottom: '12vp' }) 316 .onClick((event?: ClickEvent) => { 317 this.selfFadingFade = true; 318 }) 319 Button('子页签设置不渐隐').width('100%').margin({ bottom: '12vp' }) 320 .onClick((event?: ClickEvent) => { 321 this.selfFadingFade = false; 322 }) 323 Tabs({ barPosition: BarPosition.End, controller: this.controller }) { 324 TabContent() { 325 Column().width('100%').height('100%').backgroundColor(Color.Pink) 326 }.tabBar('pink') 327 328 TabContent() { 329 Column().width('100%').height('100%').backgroundColor(Color.Yellow) 330 }.tabBar('yellow') 331 332 TabContent() { 333 Column().width('100%').height('100%').backgroundColor(Color.Blue) 334 }.tabBar('blue') 335 336 TabContent() { 337 Column().width('100%').height('100%').backgroundColor(Color.Green) 338 }.tabBar('green') 339 340 TabContent() { 341 Column().width('100%').height('100%').backgroundColor(Color.Green) 342 }.tabBar('green') 343 344 TabContent() { 345 Column().width('100%').height('100%').backgroundColor(Color.Green) 346 }.tabBar('green') 347 348 TabContent() { 349 Column().width('100%').height('100%').backgroundColor(Color.Green) 350 }.tabBar('green') 351 352 TabContent() { 353 Column().width('100%').height('100%').backgroundColor(Color.Green) 354 }.tabBar('green') 355 } 356 .vertical(false) 357 .scrollable(true) 358 .barMode(BarMode.Scrollable) 359 .barHeight(80) 360 .animationDuration(400) 361 .onChange((index: number) => { 362 console.info(index.toString()) 363 }) 364 .fadingEdge(this.selfFadingFade) 365 .height('30%') 366 .width('100%') 367 368 Tabs({ barPosition: BarPosition.Start, controller: this.controller1 }) { 369 TabContent() { 370 Column().width('100%').height('100%').backgroundColor(Color.Pink) 371 }.tabBar('pink') 372 373 TabContent() { 374 Column().width('100%').height('100%').backgroundColor(Color.Yellow) 375 }.tabBar('yellow') 376 377 TabContent() { 378 Column().width('100%').height('100%').backgroundColor(Color.Blue) 379 }.tabBar('blue') 380 381 TabContent() { 382 Column().width('100%').height('100%').backgroundColor(Color.Green) 383 }.tabBar('green') 384 385 TabContent() { 386 Column().width('100%').height('100%').backgroundColor(Color.Green) 387 }.tabBar('green') 388 389 TabContent() { 390 Column().width('100%').height('100%').backgroundColor(Color.Green) 391 }.tabBar('green') 392 } 393 .vertical(true) 394 .scrollable(true) 395 .barMode(BarMode.Scrollable) 396 .barHeight(200) 397 .barWidth(80) 398 .animationDuration(400) 399 .onChange((index: number) => { 400 console.info(index.toString()) 401 }) 402 .fadingEdge(this.selfFadingFade) 403 .height('30%') 404 .width('100%') 405 } 406 .padding({ top: '24vp', left: '24vp', right: '24vp' }) 407 } 408} 409``` 410 411 412 413### 示例4 414 415```ts 416// xxx.ets 417@Entry 418@Component 419struct barBackgroundColorTest { 420 private controller: TabsController = new TabsController() 421 @State barOverlap: boolean = true; 422 @State barBackgroundColor: string = '#88888888'; 423 424 build() { 425 Column() { 426 Button("barOverlap变化").width('100%').margin({ bottom: '12vp' }) 427 .onClick((event?: ClickEvent) => { 428 if (this.barOverlap) { 429 this.barOverlap = false; 430 } else { 431 this.barOverlap = true; 432 } 433 }) 434 435 Tabs({ barPosition: BarPosition.Start, index: 0, controller: this.controller }) { 436 TabContent() { 437 Column() { 438 Text(`barOverlap ${this.barOverlap}`).fontSize(16).margin({ top: this.barOverlap ? '56vp' : 0 }) 439 Text(`barBackgroundColor ${this.barBackgroundColor}`).fontSize(16) 440 }.width('100%').width('100%').height('100%') 441 .backgroundColor(Color.Pink) 442 } 443 .tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), "1")) 444 445 TabContent() { 446 Column() { 447 Text(`barOverlap ${this.barOverlap}`).fontSize(16).margin({ top: this.barOverlap ? '56vp' : 0 }) 448 Text(`barBackgroundColor ${this.barBackgroundColor}`).fontSize(16) 449 }.width('100%').width('100%').height('100%') 450 .backgroundColor(Color.Yellow) 451 } 452 .tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), "2")) 453 454 TabContent() { 455 Column() { 456 Text(`barOverlap ${this.barOverlap}`).fontSize(16).margin({ top: this.barOverlap ? '56vp' : 0 }) 457 Text(`barBackgroundColor ${this.barBackgroundColor}`).fontSize(16) 458 }.width('100%').width('100%').height('100%') 459 .backgroundColor(Color.Green) 460 } 461 .tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), "3")) 462 } 463 .vertical(false) 464 .barMode(BarMode.Fixed) 465 .height('60%') 466 .barOverlap(this.barOverlap) 467 .scrollable(true) 468 .animationDuration(10) 469 .barBackgroundColor(this.barBackgroundColor) 470 } 471 .height(500) 472 .padding({ top: '24vp', left: '24vp', right: '24vp' }) 473 } 474} 475``` 476 477 478 479 480### 示例5 481 482```ts 483// xxx.ets 484@Entry 485@Component 486struct TabsExample5 { 487 private controller: TabsController = new TabsController() 488 @State gridMargin: number = 10 489 @State gridGutter: number = 10 490 @State sm: number = -2 491 @State clickedContent: string = ""; 492 493 build() { 494 Column() { 495 Row() { 496 Button("gridMargin+10 " + this.gridMargin) 497 .width('47%') 498 .height(50) 499 .margin({ top: 5 }) 500 .onClick((event?: ClickEvent) => { 501 this.gridMargin += 10 502 }) 503 .margin({ right: '6%', bottom: '12vp' }) 504 Button("gridMargin-10 " + this.gridMargin) 505 .width('47%') 506 .height(50) 507 .margin({ top: 5 }) 508 .onClick((event?: ClickEvent) => { 509 this.gridMargin -= 10 510 }) 511 .margin({ bottom: '12vp' }) 512 } 513 514 Row() { 515 Button("gridGutter+10 " + this.gridGutter) 516 .width('47%') 517 .height(50) 518 .margin({ top: 5 }) 519 .onClick((event?: ClickEvent) => { 520 this.gridGutter += 10 521 }) 522 .margin({ right: '6%', bottom: '12vp' }) 523 Button("gridGutter-10 " + this.gridGutter) 524 .width('47%') 525 .height(50) 526 .margin({ top: 5 }) 527 .onClick((event?: ClickEvent) => { 528 this.gridGutter -= 10 529 }) 530 .margin({ bottom: '12vp' }) 531 } 532 533 Row() { 534 Button("sm+2 " + this.sm) 535 .width('47%') 536 .height(50) 537 .margin({ top: 5 }) 538 .onClick((event?: ClickEvent) => { 539 this.sm += 2 540 }) 541 .margin({ right: '6%' }) 542 Button("sm-2 " + this.sm).width('47%').height(50).margin({ top: 5 }) 543 .onClick((event?: ClickEvent) => { 544 this.sm -= 2 545 }) 546 } 547 548 Text("点击内容:" + this.clickedContent).width('100%').height(200).margin({ top: 5 }) 549 550 551 Tabs({ barPosition: BarPosition.End, controller: this.controller }) { 552 TabContent() { 553 Column().width('100%').height('100%').backgroundColor(Color.Pink) 554 }.tabBar(BottomTabBarStyle.of($r("sys.media.ohos_app_icon"), "1")) 555 556 TabContent() { 557 Column().width('100%').height('100%').backgroundColor(Color.Green) 558 }.tabBar(BottomTabBarStyle.of($r("sys.media.ohos_app_icon"), "2")) 559 560 TabContent() { 561 Column().width('100%').height('100%').backgroundColor(Color.Blue) 562 }.tabBar(BottomTabBarStyle.of($r("sys.media.ohos_app_icon"), "3")) 563 } 564 .width('350vp') 565 .animationDuration(300) 566 .height('60%') 567 .barGridAlign({ sm: this.sm, margin: this.gridMargin, gutter: this.gridGutter }) 568 .backgroundColor(0xf1f3f5) 569 .onTabBarClick((index: number) => { 570 this.clickedContent += "now index " + index + " is clicked\n"; 571 }) 572 } 573 .width('100%') 574 .height(500) 575 .margin({ top: 5 }) 576 .padding('10vp') 577 } 578} 579``` 580 581 582 583### 示例6 584 585```ts 586// xxx.ets 587@Entry 588@Component 589struct TabsExample6 { 590 private controller: TabsController = new TabsController() 591 @State scrollMargin: number = 0 592 @State layoutStyle: LayoutStyle = LayoutStyle.ALWAYS_CENTER 593 @State text: string = "文本" 594 595 build() { 596 Column() { 597 Row() { 598 Button("scrollMargin+10 " + this.scrollMargin) 599 .width('47%') 600 .height(50) 601 .margin({ top: 5 }) 602 .onClick((event?: ClickEvent) => { 603 this.scrollMargin += 10 604 }) 605 .margin({ right: '6%', bottom: '12vp' }) 606 Button("scrollMargin-10 " + this.scrollMargin) 607 .width('47%') 608 .height(50) 609 .margin({ top: 5 }) 610 .onClick((event?: ClickEvent) => { 611 this.scrollMargin -= 10 612 }) 613 .margin({ bottom: '12vp' }) 614 } 615 616 Row() { 617 Button("文本增加 ") 618 .width('47%') 619 .height(50) 620 .margin({ top: 5 }) 621 .onClick((event?: ClickEvent) => { 622 this.text += '文本增加' 623 }) 624 .margin({ right: '6%', bottom: '12vp' }) 625 Button("文本重置") 626 .width('47%') 627 .height(50) 628 .margin({ top: 5 }) 629 .onClick((event?: ClickEvent) => { 630 this.text = "文本" 631 }) 632 .margin({ bottom: '12vp' }) 633 } 634 635 Row() { 636 Button("layoutStyle.ALWAYS_CENTER") 637 .width('100%') 638 .height(50) 639 .margin({ top: 5 }) 640 .fontSize(15) 641 .onClick((event?: ClickEvent) => { 642 this.layoutStyle = LayoutStyle.ALWAYS_CENTER; 643 }) 644 .margin({ bottom: '12vp' }) 645 } 646 647 Row() { 648 Button("layoutStyle.ALWAYS_AVERAGE_SPLIT") 649 .width('100%') 650 .height(50) 651 .margin({ top: 5 }) 652 .fontSize(15) 653 .onClick((event?: ClickEvent) => { 654 this.layoutStyle = LayoutStyle.ALWAYS_AVERAGE_SPLIT; 655 }) 656 .margin({ bottom: '12vp' }) 657 } 658 659 Row() { 660 Button("layoutStyle.SPACE_BETWEEN_OR_CENTER") 661 .width('100%') 662 .height(50) 663 .margin({ top: 5 }) 664 .fontSize(15) 665 .onClick((event?: ClickEvent) => { 666 this.layoutStyle = LayoutStyle.SPACE_BETWEEN_OR_CENTER; 667 }) 668 .margin({ bottom: '12vp' }) 669 } 670 671 Tabs({ barPosition: BarPosition.End, controller: this.controller }) { 672 TabContent() { 673 Column().width('100%').height('100%').backgroundColor(Color.Pink) 674 }.tabBar(SubTabBarStyle.of(this.text)) 675 676 TabContent() { 677 Column().width('100%').height('100%').backgroundColor(Color.Green) 678 }.tabBar(SubTabBarStyle.of(this.text)) 679 680 TabContent() { 681 Column().width('100%').height('100%').backgroundColor(Color.Blue) 682 }.tabBar(SubTabBarStyle.of(this.text)) 683 } 684 .animationDuration(300) 685 .height('60%') 686 .backgroundColor(0xf1f3f5) 687 .barMode(BarMode.Scrollable, { margin: this.scrollMargin, nonScrollableLayoutStyle: this.layoutStyle }) 688 } 689 .width('100%') 690 .height(500) 691 .margin({ top: 5 }) 692 .padding('24vp') 693 } 694} 695``` 696 697