• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Tabs
2
3The **\<Tabs>** component is a container component that allows users to switch between content views through tabs. Each tab page corresponds to a content view.
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
12Only the [\<TabContent>](ts-container-tabcontent.md) child component is supported.
13
14>  **NOTE**
15>
16>  If the child component has the **visibility** attribute set to **None** or **Hidden**, it is hidden but takes up space in the layout.
17
18
19## APIs
20
21Tabs(value?: {barPosition?: BarPosition, index?: number, controller?: TabsController})
22
23**Parameters**
24
25| Name        | Type                             | Mandatory  | Description                                    |
26| ----------- | --------------------------------- | ---- | ---------------------------------------- |
27| barPosition | [BarPosition](#barposition)| No   | Position of the **\<Tabs>** component.<br>Default value: **BarPosition.Start**  |
28| index       | number                            | No   | Index of the currently displayed tab.<br>Default value: **0**<br>**NOTE**<br>A value less than 0 evaluates to the default value.<br>The value ranges from 0 to the number of **\<TabContent>** subnodes minus 1.<br>When this parameter is set to different values, the slide animation for tab switching is enabled by default. To disable the animation, set **animationDuration** to **0**.<br>Since API version 10, this parameter supports [$$](../../quick-start/arkts-two-way-sync.md) for two-way binding of variables.|
29| controller  | [TabsController](#tabscontroller) | No   | Tab controller.                              |
30
31## BarPosition
32
33| Name   | Description                                      |
34| ----- | ---------------------------------------- |
35| Start | If the **vertical** attribute is set to **true**, the tab is on the left of the container. If the **vertical** attribute is set to **false**, the tab is on the top of the container.|
36| End   | If the **vertical** attribute is set to **true**, the tab is on the right of the container. If the **vertical** attribute is set to **false**, the tab is at the bottom of the container.|
37
38
39## Attributes
40
41In addition to the [universal attributes](ts-universal-attributes-size.md), the following attributes are supported.
42
43| Name                              | Type                                    | Description                                      |
44| -------------------------------- | ---------------------------------------- | ---------------------------------------- |
45| vertical                         | boolean                                  | Whether to use vertical tabs. The value **true** means to use vertical tabs, and **false** means to use horizontal tabs.<br>Default value: **false**|
46| scrollable                       | boolean                                  | Whether the tabs are scrollable. The value **true** means that the tabs are scrollable, and **false** means the opposite.<br>Default value: **true**|
47| barMode                          | [BarMode](#barmode),[ScrollableBarModeOptions](#scrollablebarmodeoptions10) | Tab bar layout mode. **BarMode** is mandatory, and **ScrollableBarModeOptions** is optional. For details, see **BarMode** and **ScrollableBarModeOptions**. Since API version 10, the optional **ScrollableBarModeOptions** parameter is supported. It is effective only when the tab bar is in scrollable mode.<br>Default value: **BarMode.Fixed**|
48| barWidth                         | number \| Length<sup>8+</sup>  | Width of the tab bar.<br>The default value varies.<br>If the tab bar has the **vertical** attribute set to **false** and does not have [SubTabBarStyle](ts-container-tabcontent.md#subtabbarstyle9) or [BottomTabBarStyle](ts-container-tabcontent.md#bottomtabbarstyle9) specified, the default value is the width of the **\<Tabs>** component.<br>If the tab bar has the **vertical** attribute set to **true** and does not have [SubTabBarStyle](ts-container-tabcontent.md#subtabbarstyle9) or [BottomTabBarStyle](ts-container-tabcontent.md#bottomtabbarstyle9) specified, the default value is **56vp**.<br>If the tab bar has the **vertical** attribute set to **false** and **SubTabbarStyle** specified, the default value is the width of the **\<Tabs>** component.<br>If the tab bar has the **vertical** attribute set to **true** and **SubTabbarStyle** specified, the default value is **56vp**.<br>If the tab bar has the **vertical** attribute set to **true** and **BottomTabbarStyle** specified, the default value is **96vp**.<br>If the tab bar has the **vertical** attribute set to **false** and **BottomTabbarStyle** specified, the default value is the width of the **\<Tabs>** component.<br>**NOTE**<br><br>A value less than 0 or greater than the width of the **\<Tabs>** component evaluates to the default value.|
49| barHeight                        | number \| Length<sup>8+</sup>  | Height of the tab bar.<br>The default value varies.<br>If the tab bar has the **vertical** attribute set to **false** and does not have a style specified, the default value is **56vp**.<br>If the tab bar has the **vertical** attribute set to **true** and does not have a style specified, the default value is the height of the **\<Tabs>** component.<br>If the tab bar has the **vertical** attribute set to **false** and **SubTabbarStyle** specified, the default value is **56vp**.<br>If the tab bar has the **vertical** attribute set to **true** and **SubTabbarStyle** specified, the default value is the height of the **\<Tabs>** component.<br>If the tab bar has the **vertical** attribute set to **true** and **BottomTabbarStyle** specified, the default value is the height of the **\<Tabs>** component.<br>If the tab bar has the **vertical** attribute set to **false** and **BottomTabbarStyle** specified, the default value is **56vp**.<br>**NOTE**<br>A value less than 0 or greater than the height of the **\<Tabs>** component evaluates to the default value.|
50| animationDuration                | number                                   | Length of time required to complete the tab switching animation that is initiated by clicking a specific tab. If this parameter is not set, no tab switching animation is displayed when a specific tab is clicked.<br>Default value: **300**<br>**NOTE**<br>This parameter cannot be set in percentage. A value less than 0 evaluates to the default value **300**.|
51| divider<sup>10+</sup>            | [DividerStyle](#dividerstyle10) \| null | Whether the divider is displayed for the **\<TabBar>** and **\<TabContent>** components and the divider style. By default, the divider is not displayed.<br> **DividerStyle**: divider style.<br> **null**: The divider is not displayed.|
52| fadingEdge<sup>10+</sup>         | boolean                                  | Whether the tab fades out when it exceeds the container width.<br>Default value: **true**<br>**NOTE**<br>It is recommended that this attribute be used together with the **barBackgroundColor** attribute. If the **barBackgroundColor** attribute is not defined, the tab fades out in white when it exceeds the container width by default.|
53| barOverlap<sup>10+</sup>         | boolean                                  | Whether the tab bar is superimposed on the **\<TabContent>** component after having its background blurred.<br>Default value: **false**|
54| barBackgroundColor<sup>10+</sup> | [ResourceColor](ts-types.md#resourcecolor) | Background color of the tab bar.<br>Default value: transparent              |
55| barGridAlign<sup>10+</sup> | [BarGridColumnOptions](#bargridcolumnoptions10) | Visible area of the tab bar in grid mode. For details, see **BarGridColumnOptions**. This attribute is effective only in horizontal mode. It is not applicable to [XS, XL, and XXL devices](../../ui/arkts-layout-development-grid-layout.md#grid-breakpoints).             |
56
57## DividerStyle<sup>10+</sup>
58
59| Name         | Type                                    | Mandatory  | Description                                      |
60| ----------- | ---------------------------------------- | ---- | ---------------------------------------- |
61| strokeWidth | [Length](ts-types.md#length)             | Yes   | Width of the divider. It cannot be set in percentage.                       |
62| color       | [ResourceColor](ts-types.md#resourcecolor) | No   | Color of the divider.<br>Default value: **#33182431**               |
63| startMargin | [Length](ts-types.md#length)             | No   | Distance between the divider and the top of the sidebar. It cannot be set in percentage.<br>Default value: **0.0**<br>Unit: vp|
64| endMargin   | [Length](ts-types.md#length)             | No   | Distance between the divider and the bottom of the sidebar. It cannot be set in percentage.<br>Default value: **0.0**<br>Unit: vp|
65
66## BarGridColumnOptions<sup>10+</sup>
67
68| Name         | Type                                    | Mandatory  | Description                                      |
69| ----------- | ---------------------------------------- | ---- | ---------------------------------------- |
70| margin | [Dimension](ts-types.md#dimension10)             | No   | Column margin in grid mode. It cannot be set in percentage.<br>Default value: **24.0**<br>Unit: vp                       |
71| gutter      | [Dimension](ts-types.md#dimension10) | No   | Column gutter (that is, gap between columns) in grid mode. It cannot be set in percentage.<br>Default value: **24.0**<br>Unit: vp                    |
72| sm | number            | No   | Number of columns occupied by a tab on a screen whose width is greater than or equal to 320 vp but less than 600 vp.<br>The value must be a non-negative even number. The default value is **-1**, indicating that the tab takes up the entire width of the tab bar.|
73| md   | number          | No   | Number of columns occupied by a tab on a screen whose width is greater than or equal to 600 vp but less than 800 vp.<br>The value must be a non-negative even number. The default value is **-1**, indicating that the tab takes up the entire width of the tab bar.|
74| lg   | number           | No   | Number of columns occupied by a tab on a screen whose width is greater than or equal to 840 vp but less than 1024 vp.<br>The value must be a non-negative even number. The default value is **-1**, indicating that the tab takes up the entire width of the tab bar.|
75
76## ScrollableBarModeOptions<sup>10+</sup>
77
78| Name         | Type                                    | Mandatory  | Description                                      |
79| ----------- | ---------------------------------------- | ---- | ---------------------------------------- |
80| margin | [Dimension](ts-types.md#dimension10)          | No   | Left and right margin of the tab bar in scrollable mode. It cannot be set in percentage.<br>Default value: **0.0**<br>Unit: vp                   |
81| nonScrollableLayoutStyle      | [LayoutStyle](#layoutstyle10) | No   | Tab layout mode of the tab bar when not scrolling in scrollable mode.<br>Default value: **LayoutStyle.ALWAYS_CENTER**          |
82
83## BarMode
84
85| Name        | Description                                      |
86| ---------- | ---------------------------------------- |
87| Scrollable | The width of each tab is determined by the actual layout. The tabs are scrollable in the following case: In horizontal layout, the total width exceeds the tab bar width; in horizontal layout, the total height exceeds the tab bar height.|
88| Fixed      | The width of each tab is determined by equally dividing the number of tabs by the bar width (or bar height in the vertical layout).|
89
90## LayoutStyle<sup>10+</sup>
91
92| Name        | Description                                      |
93| ---------- | ---------------------------------------- |
94| ALWAYS_CENTER | When the tab content exceeds the tab bar width, the tabs are scrollable.<br>Otherwise, the tabs are compactly centered and not scrollable.|
95| ALWAYS_AVERAGE_SPLITE      | When the tab content exceeds the tab bar width, the tabs are scrollable.<br>Otherwise, the tabs are not scrollable, and the tab bar width is distributed evenly between all tabs.<br>This option is valid only in horizontal mode, and is equivalent to **LayoutStyle.ALWAYS_CENTER** otherwise.|
96| SPACE_BETWEEN_OR_CENTER      | When the tab content exceeds the tab bar width, the tabs are scrollable.<br>When the tab content exceeds half of the tab bar width but still within the tab bar width, the tabs are compactly centered and not scrollable.<br>When the tab content does not exceed half of the tab bar width, the tabs are centered within half of the tab bar width, with even spacing between, and not scrollable.|
97
98## Events
99
100In addition to the [universal events](ts-universal-events-click.md), the following events are supported.
101
102| Name                                      | Description                                    |
103| ---------------------------------------- | ---------------------------------------- |
104| onChange(event: (index: number) =&gt; void) | Triggered when a tab is switched.<br>- **index**: index of the active tab. The index starts from 0.<br>This event is triggered when any of the following conditions is met:<br>1. The **\<TabContent>** component supports sliding, and the user slides on the tab bar.<br>2. The [Controller](#tabscontroller) API is called.<br>3. The attribute value is updated using a [state variable](../../quick-start/arkts-state.md).<br>4. A tab is clicked.|
105| onTabBarClick(event: (index: number) =&gt; void)<sup>10+</sup> | Triggered when a tab is clicked.<br>- **index**: index of the clicked tab. The index starts from 0.|
106
107## TabsController
108
109Defines a tab controller, which is used to control switching of tabs. One **TabsController** cannot control multiple **\<Tabs>** components.
110
111### Objects to Import
112
113```ts
114let controller: TabsController = new TabsController()
115```
116
117### changeIndex
118
119changeIndex(value: number): void
120
121Switches to the specified tab.
122
123**Parameters**
124
125| Name  | Type  | Mandatory  | Description                                    |
126| ----- | ------ | ---- | ---------------------------------------- |
127| value | number | Yes   | Index of the tab. The value starts from 0.<br>**NOTE**<br>If this parameter is set to a value less than 0 or greater than the maximum number, the default value **0** is used.|
128
129
130## Example
131
132### Example 1
133
134```ts
135// xxx.ets
136@Entry
137@Component
138struct TabsExample {
139  @State fontColor: string = '#182431'
140  @State selectedFontColor: string = '#007DFF'
141  @State currentIndex: number = 0
142  private controller: TabsController = new TabsController()
143
144  @Builder tabBuilder(index: number, name: string) {
145    Column() {
146      Text(name)
147        .fontColor(this.currentIndex === index ? this.selectedFontColor : this.fontColor)
148        .fontSize(16)
149        .fontWeight(this.currentIndex === index ? 500 : 400)
150        .lineHeight(22)
151        .margin({ top: 17, bottom: 7 })
152      Divider()
153        .strokeWidth(2)
154        .color('#007DFF')
155        .opacity(this.currentIndex === index ? 1 : 0)
156    }.width('100%')
157  }
158
159  build() {
160    Column() {
161      Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {
162        TabContent() {
163          Column().width('100%').height('100%').backgroundColor('#00CB87')
164        }.tabBar(this.tabBuilder(0, 'green'))
165
166        TabContent() {
167          Column().width('100%').height('100%').backgroundColor('#007DFF')
168        }.tabBar(this.tabBuilder(1, 'blue'))
169
170        TabContent() {
171          Column().width('100%').height('100%').backgroundColor('#FFBF00')
172        }.tabBar(this.tabBuilder(2, 'yellow'))
173
174        TabContent() {
175          Column().width('100%').height('100%').backgroundColor('#E67C92')
176        }.tabBar(this.tabBuilder(3, 'pink'))
177      }
178      .vertical(false)
179      .barMode(BarMode.Fixed)
180      .barWidth(360)
181      .barHeight(56)
182      .animationDuration(400)
183      .onChange((index: number) => {
184        this.currentIndex = index
185      })
186      .width(360)
187      .height(296)
188      .margin({ top: 52 })
189      .backgroundColor('#F1F3F5')
190    }.width('100%')
191  }
192}
193```
194
195![tabs2](figures/tabs2.gif)
196
197### Example 2
198
199```ts
200// xxx.ets
201@Entry
202@Component
203struct TabsDivider1 {
204  private controller1: TabsController = new TabsController()
205  @State dividerColor: string = 'red'
206  @State strokeWidth: number = 2
207  @State startMargin: number = 0
208  @State endMargin: number = 0
209  @State nullFlag: boolean = false
210
211  build() {
212    Column() {
213      Tabs({ controller: this.controller1 }) {
214        TabContent() {
215          Column().width('100%').height('100%').backgroundColor(Color.Pink)
216        }.tabBar('pink')
217
218        TabContent() {
219          Column().width('100%').height('100%').backgroundColor(Color.Yellow)
220        }.tabBar('yellow')
221
222        TabContent() {
223          Column().width('100%').height('100%').backgroundColor(Color.Blue)
224        }.tabBar('blue')
225
226        TabContent() {
227          Column().width('100%').height('100%').backgroundColor(Color.Green)
228        }.tabBar('green')
229
230        TabContent() {
231          Column().width('100%').height('100%').backgroundColor(Color.Red)
232        }.tabBar('red')
233      }
234      .vertical(true)
235      .scrollable(true)
236      .barMode(BarMode.Fixed)
237      .barWidth(70)
238      .barHeight(200)
239      .animationDuration(400)
240      .onChange((index: number) => {
241        console.info(index.toString())
242      })
243      .height('200vp')
244      .margin({ bottom: '12vp' })
245      .divider(this.nullFlag ? null : {
246        strokeWidth: this.strokeWidth,
247        color: this.dividerColor,
248        startMargin: this.startMargin,
249        endMargin: this.endMargin
250      })
251
252      Button ('Regular Divider').width('100%').margin({ bottom: '12vp'})
253        .onClick(() => {
254          this.nullFlag = false;
255          this.strokeWidth = 2;
256          this.dividerColor = 'red';
257          this.startMargin = 0;
258          this.endMargin = 0;
259        })
260      Button('Empty Divider').width('100%').margin({ bottom: '12vp' })
261        .onClick(() => {
262          this.nullFlag = true
263        })
264      Button('Change to Blue').width('100%').margin({ bottom: '12vp'})
265        .onClick(() => {
266          this.dividerColor = 'blue'
267        })
268      Button('Increase Width').width('100%').margin({ bottom: '12vp' })
269        .onClick(() => {
270          this.strokeWidth += 2
271        })
272      Button('Decrease Width').width('100%').margin({ bottom: '12vp'})
273        .onClick(() => {
274          if (this.strokeWidth > 2) {
275            this.strokeWidth -= 2
276          }
277        })
278      Button ('Increase Top Margin').width ('100%').margin ({ bottom:'12vp'})
279        .onClick(() => {
280          this.startMargin += 2
281        })
282      Button ('Decrease Top Margin').width ('100%').margin ({ bottom:'12vp' })
283        .onClick(() => {
284          if (this.startMargin > 2) {
285            this.startMargin -= 2
286          }
287        })
288      Button ('Increase Bottom Margin').width ('100%').margin ({ bottom:'12vp'})
289        .onClick(() => {
290          this.endMargin += 2
291        })
292      Button ('Decrease Bottom Margin').width ('100%').margin ({ bottom:'12vp' })
293        .onClick(() => {
294          if (this.endMargin > 2) {
295            this.endMargin -= 2
296          }
297        })
298    }.padding({ top: '24vp', left: '24vp', right: '24vp' })
299  }
300}
301```
302
303![tabs3](figures/tabs3.gif)
304
305### Example 3
306
307```ts
308// xxx.ets
309@Entry
310@Component
311struct TabsOpaque {
312  @State message: string = 'Hello World'
313  private controller: TabsController = new TabsController()
314  private controller1: TabsController = new TabsController()
315  @State selfFadingFade: boolean = true;
316
317  build() {
318    Column() {
319      Button (Set Tab to Fade').width ('100%').margin ({bottom: '12vp'})
320        .onClick((event?: ClickEvent) => {
321          this.selfFadingFade = true;
322        })
323      Button (Set Tab Not to Fade').width ('100%').margin ({bottom: '12vp'})
324        .onClick((event?: ClickEvent) => {
325          this.selfFadingFade = false;
326        })
327      Tabs({ barPosition: BarPosition.End, controller: this.controller }) {
328        TabContent() {
329          Column().width('100%').height('100%').backgroundColor(Color.Pink)
330        }.tabBar('pink')
331
332        TabContent() {
333          Column().width('100%').height('100%').backgroundColor(Color.Yellow)
334        }.tabBar('yellow')
335
336        TabContent() {
337          Column().width('100%').height('100%').backgroundColor(Color.Blue)
338        }.tabBar('blue')
339
340        TabContent() {
341          Column().width('100%').height('100%').backgroundColor(Color.Green)
342        }.tabBar('green')
343
344        TabContent() {
345          Column().width('100%').height('100%').backgroundColor(Color.Green)
346        }.tabBar('green')
347
348        TabContent() {
349          Column().width('100%').height('100%').backgroundColor(Color.Green)
350        }.tabBar('green')
351
352        TabContent() {
353          Column().width('100%').height('100%').backgroundColor(Color.Green)
354        }.tabBar('green')
355
356        TabContent() {
357          Column().width('100%').height('100%').backgroundColor(Color.Green)
358        }.tabBar('green')
359      }
360      .vertical(false)
361      .scrollable(true)
362      .barMode(BarMode.Scrollable)
363      .barHeight(80)
364      .animationDuration(400)
365      .onChange((index: number) => {
366        console.info(index.toString())
367      })
368      .fadingEdge(this.selfFadingFade)
369      .height('30%')
370      .width('100%')
371
372      Tabs({ barPosition: BarPosition.Start, controller: this.controller1 }) {
373        TabContent() {
374          Column().width('100%').height('100%').backgroundColor(Color.Pink)
375        }.tabBar('pink')
376
377        TabContent() {
378          Column().width('100%').height('100%').backgroundColor(Color.Yellow)
379        }.tabBar('yellow')
380
381        TabContent() {
382          Column().width('100%').height('100%').backgroundColor(Color.Blue)
383        }.tabBar('blue')
384
385        TabContent() {
386          Column().width('100%').height('100%').backgroundColor(Color.Green)
387        }.tabBar('green')
388
389        TabContent() {
390          Column().width('100%').height('100%').backgroundColor(Color.Green)
391        }.tabBar('green')
392
393        TabContent() {
394          Column().width('100%').height('100%').backgroundColor(Color.Green)
395        }.tabBar('green')
396      }
397      .vertical(true)
398      .scrollable(true)
399      .barMode(BarMode.Scrollable)
400      .barHeight(200)
401      .barWidth(80)
402      .animationDuration(400)
403      .onChange((index: number) => {
404        console.info(index.toString())
405      })
406      .fadingEdge(this.selfFadingFade)
407      .height('30%')
408      .width('100%')
409    }
410    .padding({ top: '24vp', left: '24vp', right: '24vp' })
411  }
412}
413```
414
415![tabs4](figures/tabs4.gif)
416
417### Example 4
418
419```ts
420// xxx.ets
421@Entry
422@Component
423struct barBackgroundColorTest {
424  private controller: TabsController = new TabsController()
425  @State barOverlap: boolean = true;
426  @State barBackgroundColor: string = '#88888888';
427
428  build() {
429    Column() {
430      Button ("Change barOverlap").width ('100%').margin ({ bottom:'12vp'})
431        .onClick((event?: ClickEvent) => {
432          if (this.barOverlap) {
433            this.barOverlap = false;
434          } else {
435            this.barOverlap = true;
436          }
437        })
438
439      Tabs({ barPosition: BarPosition.Start, index: 0, controller: this.controller }) {
440        TabContent() {
441          Column() {
442            Text(`barOverlap ${this.barOverlap}`).fontSize(16).margin({ top: this.barOverlap ? '56vp' : 0 })
443            Text(`barBackgroundColor ${this.barBackgroundColor}`).fontSize(16)
444          }.width('100%').width('100%').height('100%')
445          .backgroundColor(Color.Pink)
446        }
447        .tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), "1"))
448
449        TabContent() {
450          Column() {
451            Text(`barOverlap ${this.barOverlap}`).fontSize(16).margin({ top: this.barOverlap ? '56vp' : 0 })
452            Text(`barBackgroundColor ${this.barBackgroundColor}`).fontSize(16)
453          }.width('100%').width('100%').height('100%')
454          .backgroundColor(Color.Yellow)
455        }
456        .tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), "2"))
457
458        TabContent() {
459          Column() {
460            Text(`barOverlap ${this.barOverlap}`).fontSize(16).margin({ top: this.barOverlap ? '56vp' : 0 })
461            Text(`barBackgroundColor ${this.barBackgroundColor}`).fontSize(16)
462          }.width('100%').width('100%').height('100%')
463          .backgroundColor(Color.Green)
464        }
465        .tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), "3"))
466      }
467      .vertical(false)
468      .barMode(BarMode.Fixed)
469      .height('60%')
470      .barOverlap(this.barOverlap)
471      .scrollable(true)
472      .animationDuration(10)
473      .barBackgroundColor(this.barBackgroundColor)
474    }
475    .height(500)
476    .padding({ top: '24vp', left: '24vp', right: '24vp' })
477  }
478}
479```
480
481![tabs5](figures/tabs5.gif)
482
483
484### Example 5
485
486```ts
487// xxx.ets
488@Entry
489@Component
490struct TabsExample5 {
491  private controller: TabsController = new TabsController()
492  @State gridMargin: number = 10
493  @State gridGutter: number = 10
494  @State sm: number = -2
495  @State clickedContent: string = "";
496
497  build() {
498    Column() {
499      Row() {
500        Button("gridMargin+10 " + this.gridMargin)
501          .width('47%')
502          .height(50)
503          .margin({ top: 5 })
504          .onClick((event?: ClickEvent) => {
505            this.gridMargin += 10
506          })
507          .margin({ right: '6%', bottom: '12vp' })
508        Button("gridMargin-10 " + this.gridMargin)
509          .width('47%')
510          .height(50)
511          .margin({ top: 5 })
512          .onClick((event?: ClickEvent) => {
513            this.gridMargin -= 10
514          })
515          .margin({ bottom: '12vp' })
516      }
517
518      Row() {
519        Button("gridGutter+10 " + this.gridGutter)
520          .width('47%')
521          .height(50)
522          .margin({ top: 5 })
523          .onClick((event?: ClickEvent) => {
524            this.gridGutter += 10
525          })
526          .margin({ right: '6%', bottom: '12vp' })
527        Button("gridGutter-10 " + this.gridGutter)
528          .width('47%')
529          .height(50)
530          .margin({ top: 5 })
531          .onClick((event?: ClickEvent) => {
532            this.gridGutter -= 10
533          })
534          .margin({ bottom: '12vp' })
535      }
536
537      Row() {
538        Button("sm+2 " + this.sm)
539          .width('47%')
540          .height(50)
541          .margin({ top: 5 })
542          .onClick((event?: ClickEvent) => {
543            this.sm += 2
544          })
545          .margin({ right: '6%' })
546        Button("sm-2 " + this.sm).width('47%').height(50).margin({ top: 5 })
547          .onClick((event?: ClickEvent) => {
548            this.sm -= 2
549          })
550      }
551
552      Text ("Tab clicks: "+ this.clickedContent).width ('100%').height (200).margin ({ top: 5 })
553
554
555      Tabs({ barPosition: BarPosition.End, controller: this.controller }) {
556        TabContent() {
557          Column().width('100%').height('100%').backgroundColor(Color.Pink)
558        }.tabBar(BottomTabBarStyle.of($r("sys.media.ohos_app_icon"), "1"))
559
560        TabContent() {
561          Column().width('100%').height('100%').backgroundColor(Color.Green)
562        }.tabBar(BottomTabBarStyle.of($r("sys.media.ohos_app_icon"), "2"))
563
564        TabContent() {
565          Column().width('100%').height('100%').backgroundColor(Color.Blue)
566        }.tabBar(BottomTabBarStyle.of($r("sys.media.ohos_app_icon"), "3"))
567      }
568      .width('350vp')
569      .animationDuration(300)
570      .height('60%')
571      .barGridAlign({ sm: this.sm, margin: this.gridMargin, gutter: this.gridGutter })
572      .backgroundColor(0xf1f3f5)
573      .onTabBarClick((index: number) => {
574        this.clickedContent += "index " + index + " was clicked\n";
575      })
576    }
577    .width('100%')
578    .height(500)
579    .margin({ top: 5 })
580    .padding('10vp')
581  }
582}
583```
584
585![tabs5](figures/tabs6.gif)
586
587### Example 6
588
589```ts
590// xxx.ets
591@Entry
592@Component
593struct TabsExample6 {
594  private controller: TabsController = new TabsController()
595  @State scrollMargin: number = 0
596  @State layoutStyle: LayoutStyle = LayoutStyle.ALWAYS_CENTER
597  @State text: string = "Text"
598
599  build() {
600    Column() {
601      Row() {
602        Button("scrollMargin+10 " + this.scrollMargin)
603          .width('47%')
604          .height(50)
605          .margin({ top: 5 })
606          .onClick((event?: ClickEvent) => {
607            this.scrollMargin += 10
608          })
609          .margin({ right: '6%', bottom: '12vp' })
610        Button("scrollMargin-10 " + this.scrollMargin)
611          .width('47%')
612          .height(50)
613          .margin({ top: 5 })
614          .onClick((event?: ClickEvent) => {
615            this.scrollMargin -= 10
616          })
617          .margin({ bottom: '12vp' })
618      }
619
620      Row() {
621        Button ("Add Text")
622          .width('47%')
623          .height(50)
624          .margin({ top: 5 })
625          .onClick((event?: ClickEvent) => {
626            this.text += 'Add Text'
627          })
628          .margin({ right: '6%', bottom: '12vp' })
629        Button ("Reset Text")
630          .width('47%')
631          .height(50)
632          .margin({ top: 5 })
633          .onClick((event?: ClickEvent) => {
634            this.text = "Text"
635          })
636          .margin({ bottom: '12vp' })
637      }
638
639      Row() {
640        Button("layoutStyle.ALWAYS_CENTER")
641          .width('100%')
642          .height(50)
643          .margin({ top: 5 })
644          .fontSize(15)
645          .onClick((event?: ClickEvent) => {
646            this.layoutStyle = LayoutStyle.ALWAYS_CENTER;
647          })
648          .margin({ bottom: '12vp' })
649      }
650
651      Row() {
652        Button("layoutStyle.ALWAYS_AVERAGE_SPLIT")
653          .width('100%')
654          .height(50)
655          .margin({ top: 5 })
656          .fontSize(15)
657          .onClick((event?: ClickEvent) => {
658            this.layoutStyle = LayoutStyle.ALWAYS_AVERAGE_SPLIT;
659          })
660          .margin({ bottom: '12vp' })
661      }
662
663      Row() {
664        Button("layoutStyle.SPACE_BETWEEN_OR_CENTER")
665          .width('100%')
666          .height(50)
667          .margin({ top: 5 })
668          .fontSize(15)
669          .onClick((event?: ClickEvent) => {
670            this.layoutStyle = LayoutStyle.SPACE_BETWEEN_OR_CENTER;
671          })
672          .margin({ bottom: '12vp' })
673      }
674
675      Tabs({ barPosition: BarPosition.End, controller: this.controller }) {
676        TabContent() {
677          Column().width('100%').height('100%').backgroundColor(Color.Pink)
678        }.tabBar(SubTabBarStyle.of(this.text))
679
680        TabContent() {
681          Column().width('100%').height('100%').backgroundColor(Color.Green)
682        }.tabBar(SubTabBarStyle.of(this.text))
683
684        TabContent() {
685          Column().width('100%').height('100%').backgroundColor(Color.Blue)
686        }.tabBar(SubTabBarStyle.of(this.text))
687      }
688      .animationDuration(300)
689      .height('60%')
690      .backgroundColor(0xf1f3f5)
691      .barMode(BarMode.Scrollable, { margin: this.scrollMargin, nonScrollableLayoutStyle: this.layoutStyle })
692    }
693    .width('100%')
694    .height(500)
695    .margin({ top: 5 })
696    .padding('24vp')
697  }
698}
699```
700
701![tabs5](figures/tabs7.gif)
702