1# TabContent 2 3仅在Tabs中使用,对应一个切换页签的内容视图。 4 5> **说明:** 6> 7> 该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 8 9 10## 子组件 11 12支持单个子组件。 13 14> **说明:** 15> 16> 可内置系统组件和自定义组件,支持渲染控制类型([if/else](../../quick-start/arkts-rendering-control-ifelse.md)、[ForEach](../../quick-start/arkts-rendering-control-foreach.md)和[LazyForEach](../../quick-start/arkts-rendering-control-lazyforeach.md))。 17 18 19## 接口 20 21TabContent() 22 23 24## 属性 25 26除支持[通用属性](ts-universal-attributes-size.md)外,还支持以下属性: 27 28| 名称 | 参数类型 | 描述 | 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/>} | 设置TabBar上显示内容。<br/>CustomBuilder: 构造器,内部可以传入组件(API8版本以上适用)。<br/>> **说明:**<br/>> 如果icon采用svg格式图源,则要求svg图源删除其自有宽高属性值。如采用带有自有宽高属性的svg图源,icon大小则是svg本身内置的宽高属性值大小。<br>设置的内容超出tabbar页签时进行裁切。 | 31| tabBar<sup>9+</sup> | [SubTabBarStyle](#subtabbarstyle9) \| [BottomTabBarStyle](#bottomtabbarstyle9) | 设置TabBar上显示内容。<br/>SubTabBarStyle: 子页签样式,参数为文字。<br/>BottomTabBarStyle: 底部页签和侧边页签样式,参数为文字和图片。<br/>**说明:** <br/>底部样式没有下划线效果。<br/>icon异常时显示灰色图块。 | 32 33> **说明:** 34> 35> - TabContent组件不支持设置通用宽度属性,其宽度默认撑满Tabs父组件。 36> - TabContent组件不支持设置通用高度属性,其高度由Tabs父组件高度与TabBar组件高度决定。 37> - vertical属性为false值,交换上述2个限制。 38> - TabContent组件不支持内容过长时页面的滑动,如需页面滑动,可嵌套List使用。 39 40## SubTabBarStyle<sup>9+</sup> 41 42子页签样式。 43 44### constructor 45 46constructor(content: string | Resource) 47 48SubTabBarStyle的构造函数。 49 50**参数:** 51 52| 参数名 | 参数类型 | 必填 | 参数描述 | 53| -------- | -------- | -------- | -------- | 54| content | string \| [Resource](ts-types.md#resource) | 是 | 页签内的文字内容。从API version 10开始,content类型为ResourceStr。 | 55 56### of<sup>10+</sup> 57 58static of(content: ResourceStr) 59 60SubTabBarStyle的静态构造函数。 61 62**参数:** 63 64| 参数名 | 参数类型 | 必填 | 参数描述 | 65| ------- | ------------------------------------------ | ---- | ------------------ | 66| content | [ResourceStr](ts-types.md#resourcestr) | 是 | 页签内的文字内容。 | 67 68### 属性 69 70支持以下属性: 71 72| 名称 | 参数类型 | 描述 | 73| ------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | 74| indicator<sup>10+</sup> | [IndicatorStyle](#indicatorstyle10对象说明)| 设置选中子页签的下划线风格。子页签的下划线风格仅在水平模式下有效。| 75| selectedMode<sup>10+</sup> | [SelectedMode](#selectedmode10枚举说明) | 设置选中子页签的显示方式。<br />默认值:SelectedMode.INDICATOR | 76| board<sup>10+</sup> | [BoardStyle](#boardstyle10对象说明) | 设置选中子页签的背板风格。子页签的背板风格仅在水平模式下有效。| 77| labelStyle<sup>10+</sup> | [LabelStyle](#labelstyle10对象说明) | 设置子页签的label文本和字体的样式。 | 78| padding<sup>10+</sup> | [Padding](ts-types.md#padding) \| [Dimension](ts-types.md#dimension10) | 设置子页签的内边距属性(不支持百分比设置)。使用Dimension时,四个方向内边距同时生效。<br/>默认值:{left:8.0vp,right:8.0vp,top:17.0vp,bottom:18.0vp} | 79 80## IndicatorStyle<sup>10+</sup>对象说明 81 82| 名称 | 参数类型 | 必填 | 描述 | 83| -------- | -------- | -------- | -------------------------------- | 84| color | [ResourceColor](ts-types.md#resourcecolor) | 否 | 下划线的颜色和背板颜色。<br/>默认值:#FF007DFF | 85| height | [Length](ts-types.md#length) | 否 | 下划线的高度(不支持百分比设置)。<br/>默认值:2.0<br/>单位:vp | 86| width | [Length](ts-types.md#length) | 否 | 下划线的宽度(不支持百分比设置)。<br/>默认值:0.0<br/>单位:vp <br/>**说明:** <br/>宽度设置为0时,按页签文本宽度显示。| 87| borderRadius | [Length](ts-types.md#length) | 否 | 下划线的圆角半径(不支持百分比设置)。<br/>默认值:0.0<br/>单位:vp | 88| marginTop | [Length](ts-types.md#length) | 否 | 下划线与文字的间距(不支持百分比设置)。<br/>默认值:8.0<br/>单位:vp | 89 90## SelectedMode<sup>10+</sup>枚举说明 91| 名称 | 描述 | 92| ---------- | ------------------------ | 93| INDICATOR | 使用下划线模式。 | 94| BOARD | 使用背板模式。 | 95 96## BoardStyle<sup>10+</sup>对象说明 97 98| 名称 | 参数类型 | 必填 | 描述 | 99| -------- | -------- | -------- | ------------------------------------ | 100| borderRadius | [Length](ts-types.md#length) | 否 | 背板的圆角半径(不支持百分比设置)。<br/>默认值:8.0<br/>单位:vp | 101 102## LabelStyle<sup>10+</sup>对象说明 103 104| 名称 | 参数类型 | 必填 | 描述 | 105| -------------------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | 106| overflow | [TextOverflow](ts-appendix-enums.md#textoverflow) | 否 | 设置Label文本超长时的显示方式。默认值是省略号截断。 | 107| maxLines | number | 否 | 设置Label文本的最大行数。如果指定此参数,则文本最多不会超过指定的行。如果有多余的文本,可以通过textOverflow来指定截断方式。默认值是1。 | 108| minFontSize | number \| [ResourceStr](ts-types.md#resourcestr) | 否 | 设置Label文本最小显示字号(不支持百分比设置)。需配合maxFontSize以及maxLines或布局大小限制使用。自适应文本大小生效后,font.size不生效。默认值是0.0fp。| 109| maxFontSize | number \| [ResourceStr](ts-types.md#resourcestr) | 否 | 设置Label文本最大显示字号(不支持百分比设置)。需配合minFontSize以及maxLines或布局大小限制使用。自适应文本大小生效后,font.size不生效。默认值是0.0fp。|| 110| heightAdaptivePolicy | [TextHeightAdaptivePolicy](ts-appendix-enums.md#textheightadaptivepolicy10) | 否 | 设置Label文本自适应高度的方式。默认值是最大行数优先。 | 111| font | [Font](ts-types.md#font) | 否 | 设置Label文本字体样式。<br/>当页签为子页签时,默认值是字体大小16.0fp、字体类型'HarmonyOS Sans',字体风格正常,字重正常。<br/>当页签为底部页签时,默认值是字体大小10.0fp、字体类型'HarmonyOS Sans',字体风格正常,字重中等。 | 112 113## BottomTabBarStyle<sup>9+</sup> 114 115底部页签和侧边页签样式。 116 117### constructor 118 119constructor(icon: string | Resource, text: string | Resource) 120 121BottomTabBarStyle的构造函数。 122 123**参数:** 124 125| 参数名 | 参数类型 | 必填 | 参数描述 | 126| -------- | -------- | -------- | -------- | 127| icon | string \| [Resource](ts-types.md#resource) | 是 | 页签内的图片内容。从API version 10开始,icon类型为ResourceStr。 | 128| text | string \| [Resource](ts-types.md#resource) | 是 | 页签内的文字内容。从API version 10开始,text类型为ResourceStr。 | 129 130### of<sup>10+</sup> 131 132static of(icon: ResourceStr, text: ResourceStr) 133BottomTabBarStyle的静态构造函数。 134 135**参数:** 136 137| 参数名 | 参数类型 | 必填 | 参数描述 | 138| -------- | -------- | -------- | -------- | 139| icon | [ResourceStr](ts-types.md#resourcestr) | 是 | 页签内的图片内容。 | 140| text | [ResourceStr](ts-types.md#resourcestr) | 是 | 页签内的文字内容。 | 141 142### 属性 143 144支持以下属性: 145 146| 名称 | 参数类型 | 描述 | 147| ------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | 148| padding<sup>10+</sup> | [Padding](ts-types.md#padding) \| [Dimension](ts-types.md#dimension10) | 设置底部页签的内边距属性(不支持百分比设置)。使用Dimension时,四个方向内边距同时生效。<br/>默认值:{left:4.0vp,right:4.0vp,top:0.0vp,bottom:0.0vp} | 149| verticalAlign<sup>10+</sup> | [VerticalAlign](ts-appendix-enums.md#verticalalign) | 设置底部页签的图片、文字在垂直方向上的对齐格式。<br/>默认值:VerticalAlign.Center | 150| layoutMode<sup>10+</sup> | [LayoutMode](#layoutmode10枚举说明) | 设置底部页签的图片、文字排布的方式,具体参照LayoutMode枚举。<br/>默认值:LayoutMode.VERTICAL | 151| symmetricExtensible<sup>10+</sup> | boolean | 设置底部页签的图片、文字是否可以对称借左右底部页签的空余位置中的最小值,仅fixed水平模式下在底部页签之间有效。<br/>默认值:false | 152| labelStyle<sup>10+</sup> | [LabelStyle](#labelstyle10对象说明) | 设置子页签的label文本和字体的样式。 | 153 154## LayoutMode<sup>10+</sup>枚举说明 155 156| 名称 | 描述 | 157| ---------- | ---------------------------------------- | 158| AUTO | 若页签宽度大于104vp,页签内容为左右排布,否则页签内容为上下排布。仅TabBar为垂直模式或Fixed水平模式时有效。 | 159| VERTICAL | 页签内容上下排布。 | 160| HORIZONAL | 页签内容左右排布。 | 161 162 163## 示例 164 165### 示例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### 示例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### 示例3 328 329```ts 330// xxx.ets 331@Entry 332@Component 333struct TabBarStyleExample { 334 build() { 335 Column({ space: 5 }) { 336 Text("子页签样式") 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("底部页签样式") 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("侧边页签样式") 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### 示例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("下划线颜色变化").width('100%').margin({ bottom: '12vp' }) 449 .onClick((event?: ClickEvent) => { 450 // 对Button组件的宽高属性进行动画配置 451 if (this.colorFlag) { 452 animateTo({ 453 duration: 1000, // 动画时长 454 curve: Curve.Linear, // 动画曲线 455 delay: 200, // 动画延迟 456 iterations: 1, // 播放次数 457 playMode: PlayMode.Normal, // 动画模式 458 onFinish: () => { 459 console.info('play end') 460 } 461 }, () => { 462 this.indicatorColor = Color.Red 463 }) 464 } else { 465 animateTo({ 466 duration: 1000, // 动画时长 467 curve: Curve.Linear, // 动画曲线 468 delay: 200, // 动画延迟 469 iterations: 1, // 播放次数 470 playMode: PlayMode.Normal, // 动画模式 471 onFinish: () => { 472 console.info('play end') 473 } 474 }, () => { 475 this.indicatorColor = Color.Yellow 476 }) 477 } 478 this.colorFlag = !this.colorFlag 479 }) 480 Button("下划线高度变化").width('100%').margin({ bottom: '12vp' }) 481 .onClick((event?: ClickEvent) => { 482 // 对Button组件的宽高属性进行动画配置 483 if (this.heightFlag) { 484 animateTo({ 485 duration: 1000, // 动画时长 486 curve: Curve.Linear, // 动画曲线 487 delay: 200, // 动画延迟 488 iterations: 1, // 播放次数 489 playMode: PlayMode.Normal, // 动画模式 490 onFinish: () => { 491 console.info('play end') 492 } 493 }, () => { 494 this.indicatorHeight = 20 495 }) 496 } else { 497 animateTo({ 498 duration: 1000, // 动画时长 499 curve: Curve.Linear, // 动画曲线 500 delay: 200, // 动画延迟 501 iterations: 1, // 播放次数 502 playMode: PlayMode.Normal, // 动画模式 503 onFinish: () => { 504 console.info('play end') 505 } 506 }, () => { 507 this.indicatorHeight = 10 508 }) 509 } 510 this.heightFlag = !this.heightFlag 511 }) 512 Button("下划线宽度变化").width('100%').margin({ bottom: '12vp' }) 513 .onClick((event?: ClickEvent) => { 514 // 对Button组件的宽高属性进行动画配置 515 if (this.widthFlag) { 516 animateTo({ 517 duration: 1000, // 动画时长 518 curve: Curve.Linear, // 动画曲线 519 delay: 200, // 动画延迟 520 iterations: 1, // 播放次数 521 playMode: PlayMode.Normal, // 动画模式 522 onFinish: () => { 523 console.info('play end') 524 } 525 }, () => { 526 this.indicatorWidth = 30 527 }) 528 } else { 529 animateTo({ 530 duration: 1000, // 动画时长 531 curve: Curve.Linear, // 动画曲线 532 delay: 200, // 动画延迟 533 iterations: 1, // 播放次数 534 playMode: PlayMode.Normal, // 动画模式 535 onFinish: () => { 536 console.info('play end') 537 } 538 }, () => { 539 this.indicatorWidth = 50 540 }) 541 } 542 this.widthFlag = !this.widthFlag 543 }) 544 Button("下划线圆角半径变化").width('100%').margin({ bottom: '12vp' }) 545 .onClick((event?: ClickEvent) => { 546 // 对Button组件的宽高属性进行动画配置 547 if (this.borderFlag) { 548 animateTo({ 549 duration: 1000, // 动画时长 550 curve: Curve.Linear, // 动画曲线 551 delay: 200, // 动画延迟 552 iterations: 1, // 播放次数 553 playMode: PlayMode.Normal, // 动画模式 554 onFinish: () => { 555 console.info('play end') 556 } 557 }, () => { 558 this.indicatorBorderRadius = 0 559 }) 560 } else { 561 animateTo({ 562 duration: 1000, // 动画时长 563 curve: Curve.Linear, // 动画曲线 564 delay: 200, // 动画延迟 565 iterations: 1, // 播放次数 566 playMode: PlayMode.Normal, // 动画模式 567 onFinish: () => { 568 console.info('play end') 569 } 570 }, () => { 571 this.indicatorBorderRadius = 5 572 }) 573 } 574 this.borderFlag = !this.borderFlag 575 }) 576 Button("下划线间距变化").width('100%').margin({ bottom: '12vp' }) 577 .onClick((event?: ClickEvent) => { 578 // 对Button组件的宽高属性进行动画配置 579 if (this.spaceFlag) { 580 animateTo({ 581 duration: 1000, // 动画时长 582 curve: Curve.Linear, // 动画曲线 583 delay: 200, // 动画延迟 584 iterations: 1, // 播放次数 585 playMode: PlayMode.Normal, // 动画模式 586 onFinish: () => { 587 console.info('play end') 588 } 589 }, () => { 590 this.indicatorSpace = 20 591 }) 592 } else { 593 animateTo({ 594 duration: 1000, // 动画时长 595 curve: Curve.Linear, // 动画曲线 596 delay: 200, // 动画延迟 597 iterations: 1, // 播放次数 598 playMode: PlayMode.Normal, // 动画模式 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, //下划线颜色 614 height: this.indicatorHeight, //下划线高度 615 width: this.indicatorWidth, //下划线宽度 616 borderRadius: this.indicatorBorderRadius, //下划线圆角半径 617 marginTop: this.indicatorSpace //下划线与文字间距 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### 示例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('单行省略号截断').fontSize(30).fontColor(0xFF000000) 677 }.width('100%').height('100%').backgroundColor(Color.Pink) 678 }.tabBar(SubTabBarStyle.of('开始【单行省略号截断单行省略号截断单行省略号截断单行省略号截断单行省略号截断单行省略号截断单行省略号截断单行省略号截断单行省略号截断单行省略号截断】结束') 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('先缩小再截断').fontSize(30).fontColor(0xFF000000) 685 }.width('100%').height('100%').backgroundColor(Color.Pink) 686 }.tabBar(SubTabBarStyle.of('开始【先缩小再截断先缩小再截断先缩小再截断先缩小再截断先缩小再截断先缩小再截断先缩小再截断先缩小再截断先缩小再截断先缩小再截断先缩小再截断先缩小再截断先缩小再截断先缩小再截断】结束') 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('先缩小再换行再截断').fontSize(30).fontColor(0xFF000000) 692 }.width('100%').height('100%').backgroundColor(Color.Pink) 693 }.tabBar(SubTabBarStyle.of('开始【先缩小再换行再截断先缩小再换行再截断先缩小再换行再截断先缩小再换行再截断先缩小再换行再截断先缩小再换行再截断先缩小再换行再截断先缩小再换行再截断】结束') 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('换行').fontSize(30).fontColor(0xFF000000) 699 } 700 .width('100%').height('100%').backgroundColor(Color.Pink) 701 }.tabBar(SubTabBarStyle.of('开始【换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行】结束') 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### 示例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("文本增加 ") 758 .width('47%') 759 .height(50) 760 .margin({ top: 5 }) 761 .onClick((event?: ClickEvent) => { 762 this.text += '文本增加' 763 }) 764 .margin({ right: '6%', bottom: '12vp' }) 765 Button("文本重置") 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("symmetricExtensible改变 " + 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("layoutMode垂直 ") 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("layoutMode水平 ") 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朝上") 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居中") 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朝下") 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