1# TabContent 2 3The **\<TabContent>** component is used only in the **\<Tabs>** component. It corresponds to the content view of a switched tab page. 4 5> **NOTE** 6> 7> This component is supported since API version 7. Updates will be marked with a superscript to indicate their earliest API version. 8 9 10## Child Components 11 12This component supports only one child component. 13 14> **NOTE** 15> 16> Built-in components and custom components are allowed, with support for ([if/else](../../quick-start/arkts-rendering-control-ifelse.md), [ForEach](../../quick-start/arkts-rendering-control-foreach.md), and [LazyForEach](../../quick-start/arkts-rendering-control-lazyforeach.md)) rendering control. 17 18 19## APIs 20 21TabContent() 22 23 24## Attributes 25 26In addition to the [universal attributes](ts-universal-attributes-size.md), the following attributes are supported. 27 28| Name| Type| Description| 29| -------- | -------- | -------- | 30| tabBar | string \| [Resource](ts-types.md#resource) \|<br>[CustomBuilder](ts-types.md#custombuilder8)<sup>8+</sup>\| {<br>icon?: string \| [Resource](ts-types.md#resource),<br>text?: string \| [Resource](ts-types.md#resource)<br>} | Content displayed on the tab bar.<br>**CustomBuilder**: builder, to which components can be passed (applicable to API version 8 and later versions).<br>**NOTE**<br>When using an SVG image for the icon, delete the width and height attributes of the image. Otherwise, the icon size will be determined by the width and height attributes of the SVG image.<br>If the content set exceeds the space provided by the tab bar, it will be clipped.| 31| tabBar<sup>9+</sup> | [SubTabBarStyle](#subtabbarstyle9) \| [BottomTabBarStyle](#bottomtabbarstyle9) | Content displayed on the tab bar.<br>**SubTabBarStyle**: subtab style. It takes text as its input parameter.<br>**BottomTabBarStyle**: bottom and side tab style. It takes text and images as its input parameters.<br>**NOTE**<br>The bottom tab style does not include an indicator.<br>When an icon display error occurs, a gray blank block is displayed.| 32 33> **NOTE** 34> 35> - The **\<TabContent>** component does not support setting of the common width attribute. By default, its width is the same as that of the parent **\<Tabs>** component. 36> - The **\<TabContent>** component does not support setting of the universal height attribute. Its height is determined by the height of the parent **\<Tabs>** component and the **\<TabBar>** component. 37> - If the **vertical** attribute is **false**, the width and height descriptions are swapped in the preceding two restrictions. 38> - **\<TabContent>** does not support page scrolling. If page scrolling is required, consider nesting a list. 39 40## SubTabBarStyle<sup>9+</sup> 41 42Implements the subtab style. 43 44### constructor 45 46constructor(content: string | Resource) 47 48Constructor used to create a **SubTabBarStyle** instance. 49 50**Parameters** 51 52| Name| Type | Mandatory| Description| 53| -------- | -------- | -------- | -------- | 54| content | string \| [Resource](ts-types.md#resource) | Yes| Text for the tab. Since API version 10, the type of **content** is **ResourceStr**.| 55 56### of<sup>10+</sup> 57 58static of(content: ResourceStr) 59 60Static constructor used to create a **SubTabBarStyle** instance. 61 62**Parameters** 63 64| Name | Type | Mandatory| Description | 65| ------- | ------------------------------------------ | ---- | ------------------ | 66| content | [ResourceStr](ts-types.md#resourcestr) | Yes | Text for the tab.| 67 68### Attributes 69 70The following attributes are supported. 71 72| Name | Type | Description | 73| ------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | 74| indicator<sup>10+</sup> | [IndicatorStyle](#indicatorstyle10)| Indicator style of the selected subtab. It is valid only in the horizontal layout.| 75| selectedMode<sup>10+</sup> | [SelectedMode](#selectedmode10) | Display mode of the selected subtab.<br>Default value: **SelectedMode.INDICATOR**| 76| board<sup>10+</sup> | [BoardStyle](#boardstyle10) | Board style of the selected subtab. This attribute applies only | 77| labelStyle<sup>10+</sup> | [LabelStyle](#labelstyle10) | Label text and font of the subtab.| 78| padding<sup>10+</sup> | [Padding](ts-types.md#padding) \| [Dimension](ts-types.md#dimension10) | Padding of the subtab. It cannot be set in percentage. When the parameter is of the Dimension type, the value applies to all sides.<br>Default value: **{left:8.0vp,right:8.0vp,top:17.0vp,bottom:18.0vp}**| 79 80## IndicatorStyle<sup>10+</sup> 81 82| Name| Type| Mandatory| Description| 83| -------- | -------- | -------- | -------------------------------- | 84| color | [ResourceColor](ts-types.md#resourcecolor) | No| Color of the indicator and board.<br>Default value: **#FF007DFF**| 85| height | [Length](ts-types.md#length) | No| Height of the indicator. It cannot be set in percentage.<br>Default value: **2.0**<br>Unit: vp| 86| width | [Length](ts-types.md#length) | No| Width of the indicator. It cannot be set in percentage.<br>Default value: **0.0**<br>Unit: vp<br>**NOTE**<br>If this parameter is set to **0**, the tab text width will be used instead.| 87| borderRadius | [Length](ts-types.md#length) | No| Rounded corner radius of the indicator. It cannot be set in percentage.<br>Default value: **0.0**<br>Unit: vp| 88| marginTop | [Length](ts-types.md#length) | No| Spacing between the indicator and text. It cannot be set in percentage.<br>Default value: **8.0**<br>Unit: vp| 89 90## SelectedMode<sup>10+</sup> 91| Name | Description | 92| ---------- | ------------------------ | 93| INDICATOR | Indicator mode. | 94| BOARD | Board mode. | 95 96## BoardStyle<sup>10+</sup> 97 98| Name| Type| Mandatory| Description| 99| -------- | -------- | -------- | ------------------------------------ | 100| borderRadius | [Length](ts-types.md#length) | No| Rounded corner radius of the board. It cannot be set in percentage.<br>Default value: **8.0**<br>Unit: vp| 101 102## LabelStyle<sup>10+</sup> 103 104| Name | Type | Mandatory| Description | 105| -------------------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | 106| overflow | [TextOverflow](ts-appendix-enums.md#textoverflow) | No | Display mode when the label text is too long. By default, an ellipsis (...) is used to represent text overflow.| 107| maxLines | number | No | Maximum number of lines in the label text. If this attribute is specified, the text will not exceed the specified number of lines. You can use **textOverflow** to specify how to represent text overflow. Default value: **1**| 108| minFontSize | number \| [ResourceStr](ts-types.md#resourcestr) | No | Minimum font size of the label text. It cannot be set in percentage. For the setting to take effect, this attribute must be used together with **maxFontSize**, **maxLines**, or layout constraint settings. When the adaptive text size is set, **font.size** does not take effect. Default value: **0.0fp**| 109| maxFontSize | number \| [ResourceStr](ts-types.md#resourcestr) | No | Maximum font size of the label text. It cannot be set in percentage. For the setting to take effect, this attribute must be used together with **minFontSize**, **maxLines**, or layout constraint settings. When the adaptive text size is set, **font.size** does not take effect. Default value: **0.0fp**| 110| heightAdaptivePolicy | [TextHeightAdaptivePolicy](ts-appendix-enums.md#textheightadaptivepolicy10) | No | How the adaptive height is determined for the label text. By default, the **maxLines** settings are prioritized. | 111| font | [Font](ts-types.md#font) | No | Font of the label text.<br>When the tab is a subtab, the default font is in 16.0 fp size, 'HarmonyOS Sans' family, and normal font style and weight.<br>When the tab is a bottom tab, the default font is in 10.0 fp size, 'HarmonyOS Sans' family, normal font style, and medium weight. | 112 113## BottomTabBarStyle<sup>9+</sup> 114 115Implements the bottom and side tab style. 116 117### constructor 118 119constructor(icon: string | Resource, text: string | Resource) 120 121A constructor used to create a **BottomTabBarStyle** instance. 122 123**Parameters** 124 125| Name| Type | Mandatory| Description| 126| -------- | -------- | -------- | -------- | 127| icon | string \| [Resource](ts-types.md#resource) | Yes| Image for the tab. Since API version 10, the type of **icon** is **ResourceStr**.| 128| text | string \| [Resource](ts-types.md#resource) | Yes| Text for the tab. Since API version 10, the type of **text** is **ResourceStr**.| 129 130### of<sup>10+</sup> 131 132static of(icon: ResourceStr, text: ResourceStr) 133Static constructor used to create a **BottomTabBarStyle** instance. 134 135**Parameters** 136 137| Name| Type | Mandatory| Description| 138| -------- | -------- | -------- | -------- | 139| icon | [ResourceStr](ts-types.md#resourcestr) | Yes| Image for the tab.| 140| text | [ResourceStr](ts-types.md#resourcestr) | Yes| Text for the tab.| 141 142### Attributes 143 144The following attributes are supported. 145 146| Name | Type | Description | 147| ------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | 148| padding<sup>10+</sup> | [Padding](ts-types.md#padding) \| [Dimension](ts-types.md#dimension10) | Padding of the bottom tab. It cannot be set in percentage. When the parameter is of the Dimension type, the value applies to all sides.<br>Default value: **{left:4.0vp,right:4.0vp,top:0.0vp,bottom:0.0vp}**| 149| verticalAlign<sup>10+</sup> | [VerticalAlign](ts-appendix-enums.md#verticalalign) | Vertical alignment mode of the images and text on the bottom tab.<br>Default value: **VerticalAlign.Center**| 150| layoutMode<sup>10+</sup> | [LayoutMode](#layoutmode10) | Layout of the images and text on the bottom tab. For details, see **LayoutMode**.<br>Default value: **LayoutMode.VERTICAL**| 151| symmetricExtensible<sup>10+</sup> | boolean | Whether the images and text on the bottom tab can be symmetrically extended by the minimum value of the available space on the left and right bottom tabs. This parameter is valid only between bottom tabs in fixed horizontal mode.<br>Default value: **false**| 152| labelStyle<sup>10+</sup> | [LabelStyle](#labelstyle10) | Label text and font of the subtab.| 153 154## LayoutMode<sup>10+</sup> 155 156| Name | Description | 157| ---------- | ---------------------------------------- | 158| AUTO | When the tab width is greater than 104 vp, the tab content is arranged from left to right. Otherwise,the tab content is arranged from top to bottom. This parameter is valid only when the tab bar is in vertical mode or fixed horizontal mode.| 159| VERTICAL | The tab content is arranged from top to bottom.| 160| HORIZONAL | The tab content is arranged from left to right.| 161 162 163## Example 164 165### Example 1 166 167```ts 168// xxx.ets 169@Entry 170@Component 171struct TabContentExample { 172 @State fontColor: string = '#182431' 173 @State selectedFontColor: string = '#007DFF' 174 @State currentIndex: number = 0 175 private controller: TabsController = new TabsController() 176 177 @Builder tabBuilder(index: number) { 178 Column() { 179 Image(this.currentIndex === index ? '/common/public_icon_on.svg' : '/common/public_icon_off.svg') 180 .width(24) 181 .height(24) 182 .margin({ bottom: 4 }) 183 .objectFit(ImageFit.Contain) 184 Text(`Tab${index + 1}`) 185 .fontColor(this.currentIndex === index ? this.selectedFontColor : this.fontColor) 186 .fontSize(10) 187 .fontWeight(500) 188 .lineHeight(14) 189 }.width('100%') 190 } 191 192 build() { 193 Column() { 194 Tabs({ barPosition: BarPosition.End, controller: this.controller }) { 195 TabContent() { 196 Column() { 197 Text('Tab1') 198 .fontSize(36) 199 .fontColor('#182431') 200 .fontWeight(500) 201 .opacity(0.4) 202 .margin({ top: 30, bottom: 56.5 }) 203 Divider() 204 .strokeWidth(0.5) 205 .color('#182431') 206 .opacity(0.05) 207 }.width('100%') 208 }.tabBar(this.tabBuilder(0)) 209 210 TabContent() { 211 Column() { 212 Text('Tab2') 213 .fontSize(36) 214 .fontColor('#182431') 215 .fontWeight(500) 216 .opacity(0.4) 217 .margin({ top: 30, bottom: 56.5 }) 218 Divider() 219 .strokeWidth(0.5) 220 .color('#182431') 221 .opacity(0.05) 222 }.width('100%') 223 }.tabBar(this.tabBuilder(1)) 224 225 TabContent() { 226 Column() { 227 Text('Tab3') 228 .fontSize(36) 229 .fontColor('#182431') 230 .fontWeight(500) 231 .opacity(0.4) 232 .margin({ top: 30, bottom: 56.5 }) 233 Divider() 234 .strokeWidth(0.5) 235 .color('#182431') 236 .opacity(0.05) 237 }.width('100%') 238 }.tabBar(this.tabBuilder(2)) 239 240 TabContent() { 241 Column() { 242 Text('Tab4') 243 .fontSize(36) 244 .fontColor('#182431') 245 .fontWeight(500) 246 .opacity(0.4) 247 .margin({ top: 30, bottom: 56.5 }) 248 Divider() 249 .strokeWidth(0.5) 250 .color('#182431') 251 .opacity(0.05) 252 }.width('100%') 253 }.tabBar(this.tabBuilder(3)) 254 } 255 .vertical(false) 256 .barHeight(56) 257 .onChange((index: number) => { 258 this.currentIndex = index 259 }) 260 .width(360) 261 .height(190) 262 .backgroundColor('#F1F3F5') 263 .margin({ top: 38 }) 264 }.width('100%') 265 } 266} 267``` 268 269 270 271### Example 2 272 273```ts 274// xxx.ets 275@Entry 276@Component 277struct TabContentExample { 278 @State fontColor: string = '#182431' 279 @State selectedFontColor: string = '#007DFF' 280 @State currentIndex: number = 0 281 private controller: TabsController = new TabsController() 282 283 @Builder tabBuilder(index: number) { 284 Column() { 285 Image(this.currentIndex === index ? '/common/public_icon_on.svg' : '/common/public_icon_off.svg') 286 .width(24) 287 .height(24) 288 .margin({ bottom: 4 }) 289 .objectFit(ImageFit.Contain) 290 Text('Tab') 291 .fontColor(this.currentIndex === index ? this.selectedFontColor : this.fontColor) 292 .fontSize(10) 293 .fontWeight(500) 294 .lineHeight(14) 295 }.width('100%').height('100%').justifyContent(FlexAlign.Center) 296 } 297 298 build() { 299 Column() { 300 Tabs({ barPosition: BarPosition.Start, controller: this.controller }) { 301 TabContent() 302 .tabBar(this.tabBuilder(0)) 303 TabContent() 304 .tabBar(this.tabBuilder(1)) 305 TabContent() 306 .tabBar(this.tabBuilder(2)) 307 TabContent() 308 .tabBar(this.tabBuilder(3)) 309 } 310 .vertical(true) 311 .barWidth(96) 312 .barHeight(414) 313 .onChange((index: number) => { 314 this.currentIndex = index 315 }) 316 .width(96) 317 .height(414) 318 .backgroundColor('#F1F3F5') 319 .margin({ top: 52 }) 320 }.width('100%') 321 } 322} 323``` 324 325 326 327### Example 3 328 329```ts 330// xxx.ets 331@Entry 332@Component 333struct TabBarStyleExample { 334 build() { 335 Column({ space: 5 }) { 336 Text ("Subtab Style") 337 Column() { 338 Tabs({ barPosition: BarPosition.Start }) { 339 TabContent() { 340 Column().width('100%').height('100%').backgroundColor(Color.Pink) 341 }.tabBar(new SubTabBarStyle('Pink')) 342 343 TabContent() { 344 Column().width('100%').height('100%').backgroundColor(Color.Yellow) 345 }.tabBar(new SubTabBarStyle('Yellow')) 346 347 TabContent() { 348 Column().width('100%').height('100%').backgroundColor(Color.Blue) 349 }.tabBar(new SubTabBarStyle('Blue')) 350 351 TabContent() { 352 Column().width('100%').height('100%').backgroundColor(Color.Green) 353 }.tabBar(new SubTabBarStyle('Green')) 354 } 355 .vertical(false) 356 .scrollable(true) 357 .barMode(BarMode.Fixed) 358 .onChange((index: number) => { 359 console.info(index.toString()) 360 }) 361 .width('100%') 362 .backgroundColor(0xF1F3F5) 363 }.width('100%').height(200) 364 Text ("Bottom Tab Style") 365 Column() { 366 Tabs({ barPosition: BarPosition.End }) { 367 TabContent() { 368 Column().width('100%').height('100%').backgroundColor(Color.Pink) 369 }.tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), 'pink')) 370 371 TabContent() { 372 Column().width('100%').height('100%').backgroundColor(Color.Yellow) 373 }.tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), 'Yellow')) 374 375 TabContent() { 376 Column().width('100%').height('100%').backgroundColor(Color.Blue) 377 }.tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), 'Blue')) 378 379 TabContent() { 380 Column().width('100%').height('100%').backgroundColor(Color.Green) 381 }.tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), 'Green')) 382 } 383 .vertical(false) 384 .scrollable(true) 385 .barMode(BarMode.Fixed) 386 .onChange((index: number) => { 387 console.info(index.toString()) 388 }) 389 .width('100%') 390 .backgroundColor(0xF1F3F5) 391 }.width('100%').height(200) 392 Text ("Side Tab Style") 393 Column() { 394 Tabs({ barPosition: BarPosition.Start }) { 395 TabContent() { 396 Column().width('100%').height('100%').backgroundColor(Color.Pink) 397 }.tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), 'pink')) 398 399 TabContent() { 400 Column().width('100%').height('100%').backgroundColor(Color.Yellow) 401 }.tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), 'Yellow')) 402 403 TabContent() { 404 Column().width('100%').height('100%').backgroundColor(Color.Blue) 405 }.tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), 'Blue')) 406 407 TabContent() { 408 Column().width('100%').height('100%').backgroundColor(Color.Green) 409 }.tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), 'Green')) 410 } 411 .vertical(true).scrollable(true).barMode(BarMode.Fixed) 412 .onChange((index: number) => { 413 console.info(index.toString()) 414 }) 415 .width('100%') 416 .backgroundColor(0xF1F3F5) 417 }.width('100%').height(400) 418 } 419 } 420} 421``` 422 423 424 425### Example 4 426 427```ts 428// xxx.ets 429@Entry 430@Component 431struct TabsAttr { 432 private controller: TabsController = new TabsController() 433 @State indicatorColor: Color = Color.Blue; 434 @State indicatorWidth: number = 40; 435 @State indicatorHeight: number = 10; 436 @State indicatorBorderRadius: number = 5; 437 @State indicatorSpace: number = 10; 438 @State subTabBorderRadius: number = 20; 439 @State selectedMode: SelectedMode = SelectedMode.INDICATOR; 440 private colorFlag: boolean = true; 441 private widthFlag: boolean = true; 442 private heightFlag: boolean = true; 443 private borderFlag: boolean = true; 444 private spaceFlag: boolean = true; 445 446 build() { 447 Column() { 448 Button ("Change Indicator Color").width ('100%').margin ({ bottom:'12vp' }) 449 .onClick((event?: ClickEvent) => { 450 // Animation configuration for the width and height attributes of the <Button> component 451 if (this.colorFlag) { 452 animateTo({ 453 duration: 1000, // Animation duration. 454 curve: Curve.Linear, // Animation curve. 455 delay: 200, // Animation delay. 456 iterations: 1, // Number of playback times. 457 playMode: PlayMode.Normal, // Animation playback mode. 458 onFinish: () => { 459 console.info('play end') 460 } 461 }, () => { 462 this.indicatorColor = Color.Red 463 }) 464 } else { 465 animateTo({ 466 duration: 1000, // Animation duration. 467 curve: Curve.Linear, // Animation curve. 468 delay: 200, // Animation delay. 469 iterations: 1, // Number of playback times. 470 playMode: PlayMode.Normal, // Animation playback mode. 471 onFinish: () => { 472 console.info('play end') 473 } 474 }, () => { 475 this.indicatorColor = Color.Yellow 476 }) 477 } 478 this.colorFlag = !this.colorFlag 479 }) 480 Button("Change Indicator Height").width('100%').margin({ bottom: '12vp' }) 481 .onClick((event?: ClickEvent) => { 482 // Animation configuration for the width and height attributes of the <Button> component 483 if (this.heightFlag) { 484 animateTo({ 485 duration: 1000, // Animation duration. 486 curve: Curve.Linear, // Animation curve. 487 delay: 200, // Animation delay. 488 iterations: 1, // Number of playback times. 489 playMode: PlayMode.Normal, // Animation playback mode. 490 onFinish: () => { 491 console.info('play end') 492 } 493 }, () => { 494 this.indicatorHeight = 20 495 }) 496 } else { 497 animateTo({ 498 duration: 1000, // Animation duration. 499 curve: Curve.Linear, // Animation curve. 500 delay: 200, // Animation delay. 501 iterations: 1, // Number of playback times. 502 playMode: PlayMode.Normal, // Animation playback mode. 503 onFinish: () => { 504 console.info('play end') 505 } 506 }, () => { 507 this.indicatorHeight = 10 508 }) 509 } 510 this.heightFlag = !this.heightFlag 511 }) 512 Button("Change Indicator Width").width('100%').margin({ bottom: '12vp' }) 513 .onClick((event?: ClickEvent) => { 514 // Animation configuration for the width and height attributes of the <Button> component 515 if (this.widthFlag) { 516 animateTo({ 517 duration: 1000, // Animation duration. 518 curve: Curve.Linear, // Animation curve. 519 delay: 200, // Animation delay. 520 iterations: 1, // Number of playback times. 521 playMode: PlayMode.Normal, // Animation playback mode. 522 onFinish: () => { 523 console.info('play end') 524 } 525 }, () => { 526 this.indicatorWidth = 30 527 }) 528 } else { 529 animateTo({ 530 duration: 1000, // Animation duration. 531 curve: Curve.Linear, // Animation curve. 532 delay: 200, // Animation delay. 533 iterations: 1, // Number of playback times. 534 playMode: PlayMode.Normal, // Animation playback mode. 535 onFinish: () => { 536 console.info('play end') 537 } 538 }, () => { 539 this.indicatorWidth = 50 540 }) 541 } 542 this.widthFlag = !this.widthFlag 543 }) 544 Button ("Change Indicator Corner Radius").width ('100%').margin ({ bottom:'12vp' }) 545 .onClick((event?: ClickEvent) => { 546 // Animation configuration for the width and height attributes of the <Button> component 547 if (this.borderFlag) { 548 animateTo({ 549 duration: 1000, // Animation duration. 550 curve: Curve.Linear, // Animation curve. 551 delay: 200, // Animation delay. 552 iterations: 1, // Number of playback times. 553 playMode: PlayMode.Normal, // Animation playback mode. 554 onFinish: () => { 555 console.info('play end') 556 } 557 }, () => { 558 this.indicatorBorderRadius = 0 559 }) 560 } else { 561 animateTo({ 562 duration: 1000, // Animation duration. 563 curve: Curve.Linear, // Animation curve. 564 delay: 200, // Animation delay. 565 iterations: 1, // Number of playback times. 566 playMode: PlayMode.Normal, // Animation playback mode. 567 onFinish: () => { 568 console.info('play end') 569 } 570 }, () => { 571 this.indicatorBorderRadius = 5 572 }) 573 } 574 this.borderFlag = !this.borderFlag 575 }) 576 Button ("Change Indicator Spacing").width ('100%').margin ({ bottom:'12vp' }) 577 .onClick((event?: ClickEvent) => { 578 // Animation configuration for the width and height attributes of the <Button> component 579 if (this.spaceFlag) { 580 animateTo({ 581 duration: 1000, // Animation duration. 582 curve: Curve.Linear, // Animation curve. 583 delay: 200, // Animation delay. 584 iterations: 1, // Number of playback times. 585 playMode: PlayMode.Normal, // Animation playback mode. 586 onFinish: () => { 587 console.info('play end') 588 } 589 }, () => { 590 this.indicatorSpace = 20 591 }) 592 } else { 593 animateTo({ 594 duration: 1000, // Animation duration. 595 curve: Curve.Linear, // Animation curve. 596 delay: 200, // Animation delay. 597 iterations: 1, // Number of playback times. 598 playMode: PlayMode.Normal, // Animation playback mode. 599 onFinish: () => { 600 console.info('play end') 601 } 602 }, () => { 603 this.indicatorSpace = 10 604 }) 605 } 606 this.spaceFlag = !this.spaceFlag 607 }) 608 Tabs({ barPosition: BarPosition.End, controller: this.controller }) { 609 TabContent() { 610 Column().width('100%').height('100%').backgroundColor(Color.Pink).borderRadius('12vp') 611 }.tabBar(SubTabBarStyle.of('pink') 612 .indicator({ 613 color: this.indicatorColor, // Indicator color. 614 height: this.indicatorHeight, // Indicator height. 615 width: this.indicatorWidth, // Indicator width. 616 borderRadius: this.indicatorBorderRadius, // Rounded corner radius of the indicator. 617 marginTop: this.indicatorSpace // Spacing between the indicator and text. 618 }) 619 .selectedMode(this.selectedMode) 620 .board({ borderRadius: this.subTabBorderRadius }) 621 .labelStyle({}) 622 ) 623 624 TabContent() { 625 Column().width('100%').height('100%').backgroundColor(Color.Yellow).borderRadius('12vp') 626 }.tabBar('yellow') 627 628 TabContent() { 629 Column().width('100%').height('100%').backgroundColor(Color.Blue).borderRadius('12vp') 630 }.tabBar('blue') 631 632 TabContent() { 633 Column().width('100%').height('100%').backgroundColor(Color.Green).borderRadius('12vp') 634 }.tabBar('green') 635 636 TabContent() { 637 Column().width('100%').height('100%').backgroundColor(Color.Gray).borderRadius('12vp') 638 }.tabBar('gray') 639 640 TabContent() { 641 Column().width('100%').height('100%').backgroundColor(Color.Orange).borderRadius('12vp') 642 }.tabBar('orange') 643 } 644 .vertical(false) 645 .scrollable(true) 646 .barMode(BarMode.Scrollable) 647 .barHeight(140) 648 .animationDuration(400) 649 .onChange((index: number) => { 650 console.info(index.toString()) 651 }) 652 .backgroundColor(0xF5F5F5) 653 .height(320) 654 }.width('100%').height(250).padding({ top: '24vp', left: '24vp', right: '24vp' }) 655 } 656} 657``` 658 659 660 661### Example 5 662 663```ts 664// xxx.ets 665@Entry 666@Component 667struct TabsTextOverflow { 668 @State message: string = 'Hello World' 669 private controller: TabsController = new TabsController() 670 @State subTabOverflowOpaque: boolean = true; 671 build() { 672 Column() { 673 Tabs({ barPosition: BarPosition.Start, controller: this.controller }) { 674 TabContent() { 675 Column(){ 676 Text('Use an ellipsis').fontSize(30).fontColor(0xFF000000) 677 }.width('100%').height('100%').backgroundColor(Color.Pink) 678 }.tabBar (SubTabBarStyle.of ('Start [Use an ellipsis] End') 679 .labelStyle({ overflow: TextOverflow.Ellipsis, maxLines: 1, minFontSize: 10, heightAdaptivePolicy: TextHeightAdaptivePolicy.MAX_LINES_FIRST, 680 font: { size: 20 } })) 681 TabContent() { 682 Column() 683 { 684 Text('Scale down and then clip').fontSize(30).fontColor(0xFF000000) 685 }.width('100%').height('100%').backgroundColor(Color.Pink) 686 }.tabBar (SubTabBarStyle.of ('Start [Scale down and then clip; Scale down and then clip] End') 687 .labelStyle({ overflow: TextOverflow.Clip, maxLines: 1, minFontSize: 15, maxFontSize: 15, heightAdaptivePolicy: TextHeightAdaptivePolicy.MIN_FONT_SIZE_FIRST, 688 font: { size: 20 } })) 689 TabContent() { 690 Column(){ 691 Text('Scale down, start a new line, and then clip').fontSize(30).fontColor(0xFF000000) 692 }.width('100%').height('100%').backgroundColor(Color.Pink) 693 }.tabBar (SubTabBarStyle.of ('Start [Scale down, start a new line, and then clip; Scale down, start a new line, and then clip] End') 694 .labelStyle({ overflow: TextOverflow.Clip, maxLines: 2, minFontSize: 15, maxFontSize: 15, heightAdaptivePolicy: TextHeightAdaptivePolicy.MIN_FONT_SIZE_FIRST, 695 font: { size: 20 } })) 696 TabContent() { 697 Column() { 698 Text('Start a new line').fontSize(30).fontColor(0xFF000000) 699 } 700 .width('100%').height('100%').backgroundColor(Color.Pink) 701 }.tabBar(SubTabBarStyle.of('Start [Start a new line; Start a new line; Start a new line; Start a new line; Start a new line] End') 702 .labelStyle({ overflow: TextOverflow.Clip, maxLines: 10, minFontSize: 10, heightAdaptivePolicy: TextHeightAdaptivePolicy.MAX_LINES_FIRST, 703 font: { size: 20 } })) 704 } 705 .vertical(true).scrollable(true) 706 .barMode(BarMode.Fixed) 707 .barHeight(720) 708 .barWidth(200).animationDuration(400) 709 .onChange((index: number) => { 710 console.info(index.toString()) 711 }) 712 .height('100%').width('100%') 713 } 714 .height('100%') 715 } 716} 717``` 718 719 720 721### Example 6 722 723```ts 724// xxx.ets 725@Entry 726@Component 727struct TabContentExample6 { 728 private controller: TabsController = new TabsController() 729 @State text: string = "2" 730 @State tabPadding: number = 0; 731 @State symmetricExtensible: boolean = false; 732 @State layoutMode: LayoutMode = LayoutMode.VERTICAL; 733 @State verticalAlign: VerticalAlign = VerticalAlign.Center; 734 735 build() { 736 Column() { 737 Row() { 738 Button("padding+10 " + this.tabPadding) 739 .width('47%') 740 .height(50) 741 .margin({ top: 5 }) 742 .onClick((event?: ClickEvent) => { 743 this.tabPadding += 10 744 }) 745 .margin({ right: '6%', bottom: '12vp' }) 746 Button("padding-10 " + this.tabPadding) 747 .width('47%') 748 .height(50) 749 .margin({ top: 5 }) 750 .onClick((event?: ClickEvent) => { 751 this.tabPadding -= 10 752 }) 753 .margin({ bottom: '12vp' }) 754 } 755 756 Row() { 757 Button ("Add Text") 758 .width('47%') 759 .height(50) 760 .margin({ top: 5 }) 761 .onClick((event?: ClickEvent) => { 762 this.text += 'Add Text' 763 }) 764 .margin({ right: '6%', bottom: '12vp' }) 765 Button ("Reset Text") 766 .width('47%') 767 .height(50) 768 .margin({ top: 5 }) 769 .onClick((event?: ClickEvent) => { 770 this.text = "2" 771 }) 772 .margin({ bottom: '12vp' }) 773 } 774 775 Row() { 776 Button ("Set SymmetricExtensible to " + this.symmetricExtensible) 777 .width('100%') 778 .height(50) 779 .margin({ top: 5 }) 780 .onClick((event?: ClickEvent) => { 781 this.symmetricExtensible = !this.symmetricExtensible 782 }) 783 .margin({ bottom: '12vp' }) 784 } 785 786 Row() { 787 Button ("Vertical Layout") 788 .width('47%') 789 .height(50) 790 .margin({ top: 5 }) 791 .onClick((event?: ClickEvent) => { 792 this.layoutMode = LayoutMode.VERTICAL; 793 }) 794 .margin({ right: '6%', bottom: '12vp' }) 795 Button ("horizontal Layout") 796 .width('47%') 797 .height(50) 798 .margin({ top: 5 }) 799 .onClick((event?: ClickEvent) => { 800 this.layoutMode = LayoutMode.HORIZONTAL; 801 }) 802 .margin({ bottom: '12vp' }) 803 } 804 805 Row() { 806 Button ("VerticalAlign.Top") 807 .width('100%') 808 .height(50) 809 .margin({ top: 5 }) 810 .onClick((event?: ClickEvent) => { 811 this.verticalAlign = VerticalAlign.Top; 812 }) 813 .margin({ bottom: '12vp' }) 814 } 815 816 Row() { 817 Button ("VerticalAlign.Center") 818 .width('100%') 819 .height(50) 820 .margin({ top: 5 }) 821 .onClick((event?: ClickEvent) => { 822 this.verticalAlign = VerticalAlign.Center; 823 }) 824 .margin({ bottom: '12vp' }) 825 } 826 827 Row() { 828 Button ("VerticalAlign.Bottom") 829 .width('100%') 830 .height(50) 831 .margin({ top: 5 }) 832 .onClick((event?: ClickEvent) => { 833 this.verticalAlign = VerticalAlign.Bottom; 834 }) 835 .margin({ bottom: '12vp' }) 836 } 837 838 839 Tabs({ barPosition: BarPosition.End, controller: this.controller }) { 840 TabContent() { 841 Column().width('100%').height('100%').backgroundColor(Color.Pink) 842 }.tabBar(BottomTabBarStyle.of($r("sys.media.ohos_app_icon"), "1")) 843 844 TabContent() { 845 Column().width('100%').height('100%').backgroundColor(Color.Green) 846 }.tabBar(BottomTabBarStyle.of($r("sys.media.ohos_app_icon"), this.text) 847 .padding(this.tabPadding) 848 .verticalAlign(this.verticalAlign) 849 .layoutMode(this.layoutMode) 850 .symmetricExtensible(this.symmetricExtensible)) 851 852 TabContent() { 853 Column().width('100%').height('100%').backgroundColor(Color.Blue) 854 }.tabBar(BottomTabBarStyle.of($r("sys.media.ohos_app_icon"), "3")) 855 } 856 .animationDuration(300) 857 .height('60%') 858 .backgroundColor(0xf1f3f5) 859 .barMode(BarMode.Fixed) 860 } 861 .width('100%') 862 .height(500) 863 .margin({ top: 5 }) 864 .padding('24vp') 865 } 866} 867``` 868 869 870