• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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&nbsp;\|&nbsp;[Resource](ts-types.md#resource)&nbsp;\|<br/>[CustomBuilder](ts-types.md#custombuilder8)<sup>8+</sup>\|&nbsp;{<br/>icon?:&nbsp;string&nbsp;\|&nbsp;[Resource](ts-types.md#resource),<br/>text?:&nbsp;string&nbsp;\|&nbsp;[Resource](ts-types.md#resource)<br/>} | 设置TabBar上显示内容。<br/>CustomBuilder:&nbsp;构造器,内部可以传入组件(API8版本以上适用)。<br/>>&nbsp;&nbsp;**说明:**<br/>>&nbsp;如果icon采用svg格式图源,则要求svg图源删除其自有宽高属性值。如采用带有自有宽高属性的svg图源,icon大小则是svg本身内置的宽高属性值大小。<br>设置的内容超出tabbar页签时进行裁切。 |
31| tabBar<sup>9+</sup> | [SubTabBarStyle](#subtabbarstyle9) \| [BottomTabBarStyle](#bottomtabbarstyle9) | 设置TabBar上显示内容。<br/>SubTabBarStyle:&nbsp;子页签样式,参数为文字。<br/>BottomTabBarStyle:&nbsp;底部页签和侧边页签样式,参数为文字和图片。<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![tabContent](figures/tabContent1.gif)
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![tabContent](figures/tabContent2.gif)
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![tabbarStyle](figures/TabBarStyle.jpeg)
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![tabContent3](figures/tabContent3.gif)
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![tabContent4](figures/tabContent4.png)
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![tabContent4](figures/tabContent5.gif)