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>icon?: string \| [Resource](ts-types.md#resource),<br>text?: string \| [Resource](ts-types.md#resource)<br>}<br>\| [CustomBuilder](ts-types.md)<sup>8+</sup> | 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, content: 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// xxx.ets 430@Entry 431@Component 432struct TabsAttr { 433 private controller: TabsController = new TabsController() 434 @State indicatorColor: Color = Color.Blue; 435 @State indicatorWidth: number = 40; 436 @State indicatorHeight: number = 10; 437 @State indicatorBorderRadius: number = 5; 438 @State indicatorSpace: number = 10; 439 @State subTabBorderRadius: number = 20; 440 @State selectedMode: SelectedMode = SelectedMode.INDICATOR; 441 private colorFlag: boolean = true; 442 private widthFlag: boolean = true; 443 private heightFlag: boolean = true; 444 private borderFlag: boolean = true; 445 private spaceFlag: boolean = true; 446 447 build() { 448 Column() { 449 Button ("Change Indicator Color").width ('100%').margin ({ bottom:'12vp' }) 450 .onClick((event?: ClickEvent) => { 451 // Animation configuration for the width and height attributes of the <Button> component 452 if (this.colorFlag) { 453 animateTo({ 454 duration: 1000, // Animation duration. 455 curve: Curve.Linear, // Animation curve. 456 delay: 200, // Animation delay. 457 iterations: 1, // Number of playback times. 458 playMode: PlayMode.Normal, // Animation playback mode. 459 onFinish: () => { 460 console.info('play end') 461 } 462 }, () => { 463 this.indicatorColor = Color.Red 464 }) 465 } else { 466 animateTo({ 467 duration: 1000, // Animation duration. 468 curve: Curve.Linear, // Animation curve. 469 delay: 200, // Animation delay. 470 iterations: 1, // Number of playback times. 471 playMode: PlayMode.Normal, // Animation playback mode. 472 onFinish: () => { 473 console.info('play end') 474 } 475 }, () => { 476 this.indicatorColor = Color.Yellow 477 }) 478 } 479 this.colorFlag = !this.colorFlag 480 }) 481 Button("Change Indicator Height").width('100%').margin({ bottom: '12vp' }) 482 .onClick((event?: ClickEvent) => { 483 // Animation configuration for the width and height attributes of the <Button> component 484 if (this.heightFlag) { 485 animateTo({ 486 duration: 1000, // Animation duration. 487 curve: Curve.Linear, // Animation curve. 488 delay: 200, // Animation delay. 489 iterations: 1, // Number of playback times. 490 playMode: PlayMode.Normal, // Animation playback mode. 491 onFinish: () => { 492 console.info('play end') 493 } 494 }, () => { 495 this.indicatorHeight = 20 496 }) 497 } else { 498 animateTo({ 499 duration: 1000, // Animation duration. 500 curve: Curve.Linear, // Animation curve. 501 delay: 200, // Animation delay. 502 iterations: 1, // Number of playback times. 503 playMode: PlayMode.Normal, // Animation playback mode. 504 onFinish: () => { 505 console.info('play end') 506 } 507 }, () => { 508 this.indicatorHeight = 10 509 }) 510 } 511 this.heightFlag = !this.heightFlag 512 }) 513 Button("Change Indicator Width").width('100%').margin({ bottom: '12vp' }) 514 .onClick((event?: ClickEvent) => { 515 // Animation configuration for the width and height attributes of the <Button> component 516 if (this.widthFlag) { 517 animateTo({ 518 duration: 1000, // Animation duration. 519 curve: Curve.Linear, // Animation curve. 520 delay: 200, // Animation delay. 521 iterations: 1, // Number of playback times. 522 playMode: PlayMode.Normal, // Animation playback mode. 523 onFinish: () => { 524 console.info('play end') 525 } 526 }, () => { 527 this.indicatorWidth = 30 528 }) 529 } else { 530 animateTo({ 531 duration: 1000, // Animation duration. 532 curve: Curve.Linear, // Animation curve. 533 delay: 200, // Animation delay. 534 iterations: 1, // Number of playback times. 535 playMode: PlayMode.Normal, // Animation playback mode. 536 onFinish: () => { 537 console.info('play end') 538 } 539 }, () => { 540 this.indicatorWidth = 50 541 }) 542 } 543 this.widthFlag = !this.widthFlag 544 }) 545 Button ("Change Indicator Corner Radius").width ('100%').margin ({ bottom:'12vp' }) 546 .onClick((event?: ClickEvent) => { 547 // Animation configuration for the width and height attributes of the <Button> component 548 if (this.borderFlag) { 549 animateTo({ 550 duration: 1000, // Animation duration. 551 curve: Curve.Linear, // Animation curve. 552 delay: 200, // Animation delay. 553 iterations: 1, // Number of playback times. 554 playMode: PlayMode.Normal, // Animation playback mode. 555 onFinish: () => { 556 console.info('play end') 557 } 558 }, () => { 559 this.indicatorBorderRadius = 0 560 }) 561 } else { 562 animateTo({ 563 duration: 1000, // Animation duration. 564 curve: Curve.Linear, // Animation curve. 565 delay: 200, // Animation delay. 566 iterations: 1, // Number of playback times. 567 playMode: PlayMode.Normal, // Animation playback mode. 568 onFinish: () => { 569 console.info('play end') 570 } 571 }, () => { 572 this.indicatorBorderRadius = 5 573 }) 574 } 575 this.borderFlag = !this.borderFlag 576 }) 577 Button ("Change Indicator Spacing").width ('100%').margin ({ bottom:'12vp' }) 578 .onClick((event?: ClickEvent) => { 579 // Animation configuration for the width and height attributes of the <Button> component 580 if (this.spaceFlag) { 581 animateTo({ 582 duration: 1000, // Animation duration. 583 curve: Curve.Linear, // Animation curve. 584 delay: 200, // Animation delay. 585 iterations: 1, // Number of playback times. 586 playMode: PlayMode.Normal, // Animation playback mode. 587 onFinish: () => { 588 console.info('play end') 589 } 590 }, () => { 591 this.indicatorSpace = 20 592 }) 593 } else { 594 animateTo({ 595 duration: 1000, // Animation duration. 596 curve: Curve.Linear, // Animation curve. 597 delay: 200, // Animation delay. 598 iterations: 1, // Number of playback times. 599 playMode: PlayMode.Normal, // Animation playback mode. 600 onFinish: () => { 601 console.info('play end') 602 } 603 }, () => { 604 this.indicatorSpace = 10 605 }) 606 } 607 this.spaceFlag = !this.spaceFlag 608 }) 609 Tabs({ barPosition: BarPosition.End, controller: this.controller }) { 610 TabContent() { 611 Column().width('100%').height('100%').backgroundColor(Color.Pink).borderRadius('12vp') 612 }.tabBar(SubTabBarStyle.of('pink') 613 .indicator({ 614 color: this.indicatorColor, // Indicator color. 615 height: this.indicatorHeight, // Indicator height. 616 width: this.indicatorWidth, // Indicator width. 617 borderRadius: this.indicatorBorderRadius, // Rounded corner radius of the indicator. 618 marginTop: this.indicatorSpace // Spacing between the indicator and text. 619 }) 620 .selectedMode(this.selectedMode) 621 .board({ borderRadius: this.subTabBorderRadius }) 622 .labelStyle({}) 623 ) 624 625 TabContent() { 626 Column().width('100%').height('100%').backgroundColor(Color.Yellow).borderRadius('12vp') 627 }.tabBar('yellow') 628 629 TabContent() { 630 Column().width('100%').height('100%').backgroundColor(Color.Blue).borderRadius('12vp') 631 }.tabBar('blue') 632 633 TabContent() { 634 Column().width('100%').height('100%').backgroundColor(Color.Green).borderRadius('12vp') 635 }.tabBar('green') 636 637 TabContent() { 638 Column().width('100%').height('100%').backgroundColor(Color.Gray).borderRadius('12vp') 639 }.tabBar('gray') 640 641 TabContent() { 642 Column().width('100%').height('100%').backgroundColor(Color.Orange).borderRadius('12vp') 643 }.tabBar('orange') 644 } 645 .vertical(false) 646 .scrollable(true) 647 .barMode(BarMode.Scrollable) 648 .barHeight(140) 649 .animationDuration(400) 650 .onChange((index: number) => { 651 console.info(index.toString()) 652 }) 653 .backgroundColor(0xF5F5F5) 654 .height(320) 655 }.width('100%').height(250).padding({ top: '24vp', left: '24vp', right: '24vp' }) 656 } 657} 658``` 659 660 661 662### Example 5 663 664```ts 665// xxx.ets 666@Entry 667@Component 668struct TabsTextOverflow { 669 @State message: string = 'Hello World' 670 private controller: TabsController = new TabsController() 671 @State subTabOverflowOpaque: boolean = true; 672 build() { 673 Column() { 674 Tabs({ barPosition: BarPosition.Start, controller: this.controller }) { 675 TabContent() { 676 Column(){ 677 Text('Use an ellipsis').fontSize(30).fontColor(0xFF000000) 678 }.width('100%').height('100%').backgroundColor(Color.Pink) 679 }.tabBar (SubTabBarStyle.of ('Start [Use an ellipsis] End') 680 .labelStyle({ overflow: TextOverflow.Ellipsis, maxLines: 1, minFontSize: 10, heightAdaptivePolicy: TextHeightAdaptivePolicy.MAX_LINES_FIRST, 681 font: { size: 20 } })) 682 TabContent() { 683 Column() 684 { 685 Text('Scale down and then clip').fontSize(30).fontColor(0xFF000000) 686 }.width('100%').height('100%').backgroundColor(Color.Pink) 687 }.tabBar (SubTabBarStyle.of ('Start [Scale down and then clip; Scale down and then clip] End') 688 .labelStyle({ overflow: TextOverflow.Clip, maxLines: 1, minFontSize: 15, maxFontSize: 15, heightAdaptivePolicy: TextHeightAdaptivePolicy.MIN_FONT_SIZE_FIRST, 689 font: { size: 20 } })) 690 TabContent() { 691 Column(){ 692 Text('Scale down, start a new line, and then clip').fontSize(30).fontColor(0xFF000000) 693 }.width('100%').height('100%').backgroundColor(Color.Pink) 694 }.tabBar (SubTabBarStyle.of ('Start [Scale down, start a new line, and then clip; Scale down, start a new line, and then clip] End') 695 .labelStyle({ overflow: TextOverflow.Clip, maxLines: 2, minFontSize: 15, maxFontSize: 15, heightAdaptivePolicy: TextHeightAdaptivePolicy.MIN_FONT_SIZE_FIRST, 696 font: { size: 20 } })) 697 TabContent() { 698 Column() { 699 Text('Start a new line').fontSize(30).fontColor(0xFF000000) 700 } 701 .width('100%').height('100%').backgroundColor(Color.Pink) 702 }.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') 703 .labelStyle({ overflow: TextOverflow.Clip, maxLines: 10, minFontSize: 10, heightAdaptivePolicy: TextHeightAdaptivePolicy.MAX_LINES_FIRST, 704 font: { size: 20 } })) 705 } 706 .vertical(true).scrollable(true) 707 .barMode(BarMode.Fixed) 708 .barHeight(720) 709 .barWidth(200).animationDuration(400) 710 .onChange((index: number) => { 711 console.info(index.toString()) 712 }) 713 .height('100%').width('100%') 714 } 715 .height('100%') 716 } 717} 718``` 719 720 721 722### Example 6 723 724```ts 725// xxx.ets 726@Entry 727@Component 728struct TabContentExample6 { 729 private controller: TabsController = new TabsController() 730 @State text: string = "2" 731 @State tabPadding: number = 0; 732 @State symmetricExtensible: boolean = false; 733 @State layoutMode: LayoutMode = LayoutMode.VERTICAL; 734 @State verticalAlign: VerticalAlign = VerticalAlign.Center; 735 736 build() { 737 Column() { 738 Row() { 739 Button("padding+10 " + this.tabPadding) 740 .width('47%') 741 .height(50) 742 .margin({ top: 5 }) 743 .onClick((event?: ClickEvent) => { 744 this.tabPadding += 10 745 }) 746 .margin({ right: '6%', bottom: '12vp' }) 747 Button("padding-10 " + this.tabPadding) 748 .width('47%') 749 .height(50) 750 .margin({ top: 5 }) 751 .onClick((event?: ClickEvent) => { 752 this.tabPadding -= 10 753 }) 754 .margin({ bottom: '12vp' }) 755 } 756 757 Row() { 758 Button ("Add Text") 759 .width('47%') 760 .height(50) 761 .margin({ top: 5 }) 762 .onClick((event?: ClickEvent) => { 763 this.text += 'Add Text' 764 }) 765 .margin({ right: '6%', bottom: '12vp' }) 766 Button ("Reset Text") 767 .width('47%') 768 .height(50) 769 .margin({ top: 5 }) 770 .onClick((event?: ClickEvent) => { 771 this.text = "2" 772 }) 773 .margin({ bottom: '12vp' }) 774 } 775 776 Row() { 777 Button ("Set SymmetricExtensible to " + this.symmetricExtensible) 778 .width('100%') 779 .height(50) 780 .margin({ top: 5 }) 781 .onClick((event?: ClickEvent) => { 782 this.symmetricExtensible = !this.symmetricExtensible 783 }) 784 .margin({ bottom: '12vp' }) 785 } 786 787 Row() { 788 Button ("Vertical Layout") 789 .width('47%') 790 .height(50) 791 .margin({ top: 5 }) 792 .onClick((event?: ClickEvent) => { 793 this.layoutMode = LayoutMode.VERTICAL; 794 }) 795 .margin({ right: '6%', bottom: '12vp' }) 796 Button ("horizontal Layout") 797 .width('47%') 798 .height(50) 799 .margin({ top: 5 }) 800 .onClick((event?: ClickEvent) => { 801 this.layoutMode = LayoutMode.HORIZONTAL; 802 }) 803 .margin({ bottom: '12vp' }) 804 } 805 806 Row() { 807 Button ("VerticalAlign.Top") 808 .width('100%') 809 .height(50) 810 .margin({ top: 5 }) 811 .onClick((event?: ClickEvent) => { 812 this.verticalAlign = VerticalAlign.Top; 813 }) 814 .margin({ bottom: '12vp' }) 815 } 816 817 Row() { 818 Button ("VerticalAlign.Center") 819 .width('100%') 820 .height(50) 821 .margin({ top: 5 }) 822 .onClick((event?: ClickEvent) => { 823 this.verticalAlign = VerticalAlign.Center; 824 }) 825 .margin({ bottom: '12vp' }) 826 } 827 828 Row() { 829 Button ("VerticalAlign.Bottom") 830 .width('100%') 831 .height(50) 832 .margin({ top: 5 }) 833 .onClick((event?: ClickEvent) => { 834 this.verticalAlign = VerticalAlign.Bottom; 835 }) 836 .margin({ bottom: '12vp' }) 837 } 838 839 840 Tabs({ barPosition: BarPosition.End, controller: this.controller }) { 841 TabContent() { 842 Column().width('100%').height('100%').backgroundColor(Color.Pink) 843 }.tabBar(BottomTabBarStyle.of($r("sys.media.ohos_app_icon"), "1")) 844 845 TabContent() { 846 Column().width('100%').height('100%').backgroundColor(Color.Green) 847 }.tabBar(BottomTabBarStyle.of($r("sys.media.ohos_app_icon"), this.text) 848 .padding(this.tabPadding) 849 .verticalAlign(this.verticalAlign) 850 .layoutMode(this.layoutMode) 851 .symmetricExtensible(this.symmetricExtensible)) 852 853 TabContent() { 854 Column().width('100%').height('100%').backgroundColor(Color.Blue) 855 }.tabBar(BottomTabBarStyle.of($r("sys.media.ohos_app_icon"), "3")) 856 } 857 .animationDuration(300) 858 .height('60%') 859 .backgroundColor(0xf1f3f5) 860 .barMode(BarMode.Fixed) 861 } 862 .width('100%') 863 .height(500) 864 .margin({ top: 5 }) 865 .padding('24vp') 866 } 867} 868``` 869 870 871