1# Tabs
2
3通过页签进行内容视图切换的容器组件,每个页签对应一个内容视图。
4
5>  **说明:**
6>
7>  该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
8>
9>  该组件从API Version 11开始默认支持安全区避让特性(默认值为:expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])),开发者可以重写该属性覆盖默认行为,API Version 11之前的版本需配合[expandSafeArea](ts-universal-attributes-expand-safe-area.md)属性实现安全区避让。
10
11
12## 子组件
13
14不支持自定义组件作为子组件, 仅可包含子组件[TabContent](ts-container-tabcontent.md), 以及渲染控制类型[if/else](../../../quick-start/arkts-rendering-control-ifelse.md)和[ForEach](../../../quick-start/arkts-rendering-control-foreach.md), 并且if/else和ForEach下也仅支持TabContent, 不支持自定义组件。
15
16>  **说明:**
17>
18>  Tabs子组件的visibility属性设置为None,或者visibility属性设置为Hidden时,对应子组件不显示,但依然会在视窗内占位。
19
20
21## 接口
22
23Tabs(value?: {barPosition?: BarPosition, index?: number, controller?: TabsController})
24
25**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
26
27**系统能力:** SystemCapability.ArkUI.ArkUI.Full
28
29**参数:**
30
31| 参数名         | 类型                              | 必填   | 说明                                     |
32| ----------- | --------------------------------- | ---- | ---------------------------------------- |
33| barPosition | [BarPosition](#barposition枚举说明)| 否    | 设置Tabs的页签位置。<br/>默认值:BarPosition.Start   |
34| index       | number                            | 否    | 设置当前显示页签的索引。<br/>默认值:0<br/>**说明:** <br/>设置为小于0的值时按默认值显示。<br/>可选值为[0, TabContent子节点数量-1]。<br/>直接修改index跳页时,切换动效不生效。 使用TabController的changeIndex时,默认生效切换动效,可以设置animationDuration为0关闭动画。<br />从API version 10开始,该参数支持[$$](../../../quick-start/arkts-two-way-sync.md)双向绑定变量。 |
35| controller  | [TabsController](#tabscontroller) | 否    | 设置Tabs控制器。                               |
36
37## BarPosition枚举说明
38
39Tabs页签位置枚举。
40
41**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
42
43**系统能力:** SystemCapability.ArkUI.ArkUI.Full
44
45| 名称  | 说明                                                         |
46| ----- | ------------------------------------------------------------ |
47| Start | vertical属性方法设置为true时,页签位于容器左侧;vertical属性方法设置为false时,页签位于容器顶部。 |
48| End   | vertical属性方法设置为true时,页签位于容器右侧;vertical属性方法设置为false时,页签位于容器底部。 |
49
50
51## 属性
52
53除支持[通用属性](ts-universal-attributes-size.md)外,还支持以下属性:
54
55### vertical
56
57vertical(value: boolean)
58
59设置是否为纵向Tab。
60
61**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
62
63**系统能力:** SystemCapability.ArkUI.ArkUI.Full
64
65**参数:** 
66
67| 参数名 | 类型    | 必填 | 说明                                                         |
68| ------ | ------- | ---- | ------------------------------------------------------------ |
69| value  | boolean | 是   | 是否为纵向Tab。<br/>默认值:false,横向Tabs,为true时纵向Tabs。<br/>当横向Tabs设置height为auto时,Tabs组件高度自适应子组件高度,即为tabBar高度+divider线宽+TabContent高度+上下padding值+上下border宽度。<br/>当纵向Tabs设置width为auto时,Tabs组件宽度自适应子组件宽度,即为tabBar宽度+divider线宽+TabContent宽度+左右padding值+左右border宽度。<br/>尽量保持每一个页面中的子组件尺寸大小一致,避免滑动页面时出现页面切换动画跳动现象。 |
70
71### scrollable
72
73scrollable(value: boolean)
74
75设置是否可以通过滑动页面进行页面切换。
76
77**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
78
79**系统能力:** SystemCapability.ArkUI.ArkUI.Full
80
81**参数:** 
82
83| 参数名 | 类型    | 必填 | 说明                                                         |
84| ------ | ------- | ---- | ------------------------------------------------------------ |
85| value  | boolean | 是   | 是否可以通过滑动页面进行页面切换。<br/>默认值:true,可以通过滑动页面进行页面切换。为false时不可滑动切换页面。 |
86
87### barMode
88
89barMode(value: BarMode, options?: ScrollableBarModeOptions)
90
91设置TabBar布局模式。
92
93**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
94
95**系统能力:** SystemCapability.ArkUI.ArkUI.Full
96
97**参数:** 
98
99| 参数名                | 类型                                                         | 必填 | 说明                                                         |
100| --------------------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ |
101| value                 | [BarMode](#barmode枚举说明)                                  | 是   | 布局模式。<br/>默认值:BarMode.Fixed                                                 |
102| options<sup>10+</sup> | [ScrollableBarModeOptions](#scrollablebarmodeoptions10对象说明) | 否   | Scrollable模式下的TabBar的布局样式。<br/>**说明:** <br/>仅Scrollable且水平模式下有效。 |
103
104### barMode<sup>10+</sup>
105
106barMode(value: BarMode.Fixed)
107
108设置TabBar布局模式为BarMode.Fixed109
110**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
111
112**系统能力:** SystemCapability.ArkUI.ArkUI.Full
113
114**参数:** 
115
116| 参数名    | 类型                             | 必填 | 说明                                    |
117| -------- | -------------------------------- | ---- | ------------------------------------ |
118| value    | [BarMode.Fixed](#barmode枚举说明) | 是   | 所有TabBar会平均分配barWidth宽度(纵向时平均分配barHeight高度)。   |
119
120### barMode<sup>10+</sup>
121
122barMode(value: BarMode.Scrollable, options: ScrollableBarModeOptions)
123
124设置TabBar布局模式为BarMode.Scrollable125
126**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
127
128**系统能力:** SystemCapability.ArkUI.ArkUI.Full
129
130**参数:** 
131
132| 参数名    | 类型                              | 必填 | 说明                                    |
133| -------- | --------------------------------- | ---- | ------------------------------------- |
134| value    | [BarMode.Scrollable](#barmode枚举说明) | 是   | 所有TabBar都使用实际布局宽度,超过总宽度(横向Tabs的barWidth,纵向Tabs的barHeight)后可滑动。        |
135| options | [ScrollableBarModeOptions](#scrollablebarmodeoptions10对象说明) | 是   | Scrollable模式下的TabBar的布局样式。<br/>**说明:** <br/>仅水平模式下有效。  |
136
137### barWidth
138
139barWidth(value: Length)
140
141设置TabBar的宽度值。设置为小于0或大于Tabs宽度值时,按默认值显示。
142
143**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
144
145**系统能力:** SystemCapability.ArkUI.ArkUI.Full
146
147**参数:** 
148
149| 参数名 | 类型                                      | 必填 | 说明                                                         |
150| ------ | ----------------------------------------- | ---- | ------------------------------------------------------------ |
151| value  | [Length](ts-types.md#length)<sup>8+</sup> | 是   | TabBar的宽度值。<br/>默认值:<br/>未设置[SubTabBarStyle](ts-container-tabcontent.md#subtabbarstyle9对象说明)和[BottomTabBarStyle](ts-container-tabcontent.md#bottomtabbarstyle9对象说明)的TabBar且vertical属性为false时,默认值为Tabs的宽度。<br/>未设置SubTabBarStyle和BottomTabBarStyle的TabBar且vertical属性为true时,默认值为56vp。<br/>设置SubTabBarStyle样式且vertical属性为false时,默认值为Tabs的宽度。<br/>设置SubTabBarStyle样式且vertical属性为true时,默认值为56vp。<br/>设置BottomTabBarStyle样式且vertical属性为true时,默认值为96vp。<br/>设置BottomTabBarStyle样式且vertical属性为false时,默认值为Tabs的宽度。 |
152
153### barHeight
154
155barHeight(value: Length)
156
157设置TabBar的高度值。设置为'auto'时,TabBar自适应子组件高度,仅在水平模式下有效。设置为小于0或大于Tabs高度值时,按默认值显示。若设置barHeight为固定值后,TabBar无法扩展底部安全区。
158
159**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
160
161**系统能力:** SystemCapability.ArkUI.ArkUI.Full
162
163**参数:** 
164
165| 参数名 | 类型                                      | 必填 | 说明                                                         |
166| ------ | ----------------------------------------- | ---- | ------------------------------------------------------------ |
167| value  | [Length](ts-types.md#length)<sup>8+</sup> | 是   | TabBar的高度值。<br/>默认值:<br/>未设置带样式的TabBar且vertical属性为false时,默认值为56vp。<br/>未设置带样式的TabBar且vertical属性为true时,默认值为Tabs的高度。<br/>设置[SubTabBarStyle](ts-container-tabcontent.md#subtabbarstyle9对象说明)样式且vertical属性为false时,默认值为56vp。<br/>设置SubTabBarStyle样式且vertical属性为true时,默认值为Tabs的高度。<br/>设置[BottomTabBarStyle](ts-container-tabcontent.md#bottomtabbarstyle9对象说明)样式且vertical属性为true时,默认值为Tabs的高度。<br/>设置BottomTabBarStyle样式且vertical属性为false时,默认值为56vp, 从API Version 12开始,默认值变更为52vp。 |
168
169### animationDuration
170
171animationDuration(value: number)
172
173设置点击TabBar页签和调用TabsController的changeIndex接口切换TabContent的动画时长。该参数不支持百分比设置。
174
175**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
176
177**系统能力:** SystemCapability.ArkUI.ArkUI.Full
178
179**参数:** 
180
181| 参数名 | 类型   | 必填 | 说明                                                         |
182| ------ | ------ | ---- | ------------------------------------------------------------ |
183| value  | number | 是   | 点击TabBar页签和调用TabsController的changeIndex接口切换TabContent的动画时长。<br/>默认值:<br/>API version 10及以前,不设置该属性或设置为null时,默认值为0,即点击TabBar页签和调用TabsController的changeIndex接口切换TabContent无动画。设置为小于0或undefined时,默认值为300。<br/>API version 11及以后,不设置该属性或设置为异常值,且设置TabBar为BottomTabBarStyle样式时,默认值为0。设置TabBar为其他样式时,默认值为300。<br/>单位:ms |
184
185### animationMode<sup>12+</sup>
186
187animationMode(mode: Optional\<AnimationMode\>)
188
189设置点击TabBar页签时切换TabContent的动画形式。
190
191**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
192
193**系统能力:** SystemCapability.ArkUI.ArkUI.Full
194
195**参数:**
196
197| 参数名 | 类型   | 必填 | 说明                                                         |
198| ------ | ------ | ---- | ------------------------------------------------------------ |
199| mode  | Optional\<[AnimationMode](#animationmode12枚举说明)\> | 是   | 点击TabBar页签时切换TabContent的动画形式。<br/>默认值:<br/>默认值是AnimationMode.CONTENT_FIRST,表示在点击TabBar切换TabContent时,先加载目标页内容,再开始切换动画。|
200
201### barPosition<sup>9+</sup>
202
203barPosition(value: BarPosition)
204
205设置Tabs的页签位置。
206
207**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
208
209**系统能力:** SystemCapability.ArkUI.ArkUI.Full
210
211**参数:** 
212
213| 参数名 | 类型                               | 必填 | 说明                  |
214| ----- | ---------------------------------- | ---- | -------------------- |
215| value | [BarPosition](#barposition枚举说明)| 是  | 设置Tabs的页签位置。<br/>默认值:BarPosition.Start   |
216
217### divider<sup>10+</sup>
218
219divider(value: DividerStyle | null)
220
221设置区分TabBar和TabContent的分割线样式。
222
223**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
224
225**系统能力:** SystemCapability.ArkUI.ArkUI.Full
226
227**参数:** 
228
229| 参数名 | 类型                                                      | 必填 | 说明                                                         |
230| ------ | --------------------------------------------------------- | ---- | ------------------------------------------------------------ |
231| value  | [DividerStyle](#dividerstyle10对象说明)&nbsp;\|&nbsp;null | 是   | 分割线样式,默认不显示分割线。<br/>DividerStyle: 分割线的样式;<br/>null: 不显示分割线。 |
232
233### fadingEdge<sup>10+</sup>
234
235fadingEdge(value: boolean)
236
237设置页签超过容器宽度时是否渐隐消失。建议配合barBackgroundColor属性一起使用,如果barBackgroundColor属性没有定义,会默认显示页签末端为白色的渐隐效果。
238
239**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
240
241**系统能力:** SystemCapability.ArkUI.ArkUI.Full
242
243**参数:** 
244
245| 参数名 | 类型    | 必填 | 说明                                               |
246| ------ | ------- | ---- | -------------------------------------------------- |
247| value  | boolean | 是   | 页签超过容器宽度时是否渐隐消失。<br />默认值:true |
248
249### barOverlap<sup>10+</sup>
250
251barOverlap(value: boolean)
252
253设置TabBar是否背后变模糊并叠加在TabContent之上。若设置barOverlap为true,TabBar默认背景色修改为'#F2F1F3F5'并添加模糊效果。
254
255**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
256
257**系统能力:** SystemCapability.ArkUI.ArkUI.Full
258
259**参数:** 
260
261| 参数名 | 类型    | 必填 | 说明                                                         |
262| ------ | ------- | ---- | ------------------------------------------------------------ |
263| value  | boolean | 是   | TabBar是否背后变模糊并叠加在TabContent之上。<br />默认值:false |
264
265### barBackgroundColor<sup>10+</sup>
266
267barBackgroundColor(value: ResourceColor)
268
269设置TabBar的背景颜色。
270
271**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
272
273**系统能力:** SystemCapability.ArkUI.ArkUI.Full
274
275**参数:** 
276
277| 参数名 | 类型                                       | 必填 | 说明                                 |
278| ------ | ------------------------------------------ | ---- | ------------------------------------ |
279| value  | [ResourceColor](ts-types.md#resourcecolor) | 是   | TabBar的背景颜色。<br />默认值:Color.Transparent,透明 |
280
281### barBackgroundBlurStyle<sup>11+</sup>
282
283barBackgroundBlurStyle(value: BlurStyle)
284
285设置TabBar的背景模糊材质。
286
287**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
288
289**系统能力:** SystemCapability.ArkUI.ArkUI.Full
290
291**参数:** 
292
293| 参数名 | 类型                                         | 必填 | 说明                                     |
294| ------ | -------------------------------------------- | ---- | ---------------------------------------- |
295| value  | [BlurStyle](ts-universal-attributes-background.md#blurstyle9) | 是   | TabBar的背景模糊材质。<br />默认值:BlurStyle.NONE |
296
297### barBackgroundBlurStyle<sup>14+</sup>
298
299barBackgroundBlurStyle(value: BlurStyle, options: BackgroundBlurStyleOptions)
300
301为TabBar提供一种在背景和内容之间的模糊能力,通过枚举值的方式封装了不同的模糊半径、蒙版颜色、蒙版透明度、饱和度、亮度。
302
303**原子化服务API:** 从API version 14开始,该接口支持在原子化服务中使用。
304
305**系统能力:** SystemCapability.ArkUI.ArkUI.Full
306
307**参数:** 
308
309| 参数名                | 类型                                                         | 必填 | 说明                                                         |
310| --------------------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ |
311| value                 | [BlurStyle](ts-universal-attributes-background.md#blurstyle9)                 | 是   | 背景模糊样式。模糊样式中封装了模糊半径、蒙版颜色、蒙版透明度、饱和度、亮度五个参数。 |
312| options | [BackgroundBlurStyleOptions](ts-universal-attributes-background.md#backgroundblurstyleoptions10对象说明) | 是   | 背景模糊选项。   
313
314### barGridAlign<sup>10+</sup>
315
316barGridAlign(value: BarGridColumnOptions)
317
318以栅格化方式设置TabBar的可见区域。具体参见BarGridColumnOptions对象。仅水平模式下有效,[不适用于XS、XL和XXL设备](../../../ui/arkts-layout-development-grid-layout.md#栅格系统断点)。
319
320**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
321
322**系统能力:** SystemCapability.ArkUI.ArkUI.Full
323
324**参数:** 
325
326| 参数名 | 类型                                                    | 必填 | 说明                               |
327| ------ | ------------------------------------------------------- | ---- | ---------------------------------- |
328| value  | [BarGridColumnOptions](#bargridcolumnoptions10对象说明) | 是   | 以栅格化方式设置TabBar的可见区域。 |
329
330### edgeEffect<sup>12+</sup>
331
332edgeEffect(edgeEffect: Optional&lt;EdgeEffect&gt;)
333
334设置边缘回弹效果。
335
336**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
337
338**系统能力:** SystemCapability.ArkUI.ArkUI.Full
339
340**参数:** 
341
342| 参数名 | 类型                                          | 必填 | 说明                                         |
343| ------ | --------------------------------------------- | ---- | -------------------------------------------- |
344| edgeEffect  | Optional&lt;[EdgeEffect](ts-appendix-enums.md#edgeeffect)&gt; | 是   | 边缘滑动效果。<br/>默认值:EdgeEffect.Spring |
345
346### barBackgroundEffect<sup>14+</sup>
347
348barBackgroundEffect(options: BackgroundEffectOptions)
349
350设置TabBar背景属性,包含背景模糊半径,亮度,饱和度,颜色等参数。
351
352**原子化服务API:** 从API version 14开始,该接口支持在原子化服务中使用。
353
354**系统能力:** SystemCapability.ArkUI.ArkUI.Full
355
356**参数:** 
357
358| 参数名  | 类型                                                         | 必填 | 说明                                       |
359| ------- | ------------------------------------------------------------ | ---- | ------------------------------------------ |
360| options | [BackgroundEffectOptions](ts-universal-attributes-background.md#backgroundeffectoptions11) | 是   | 设置TabBar背景属性包括:模糊半径,亮度,饱和度,颜色等。 |
361
362## DividerStyle<sup>10+</sup>对象说明
363
364分割线样式对象。
365
366**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
367
368**系统能力:** SystemCapability.ArkUI.ArkUI.Full
369
370| 名称          | 类型                                     | 必填   | 说明                                       |
371| ----------- | ---------------------------------------- | ---- | ---------------------------------------- |
372| strokeWidth | [Length](ts-types.md#length)             | 是    | 分割线的线宽(不支持百分比设置)。<br/>默认值:0.0<br/>单位:vp           |
373| color       | [ResourceColor](ts-types.md#resourcecolor) | 否    | 分割线的颜色。<br/>默认值:#33182431                |
374| startMargin | [Length](ts-types.md#length)             | 否    | 分割线与侧边栏顶端的距离(不支持百分比设置)。<br/>默认值:0.0<br/>单位:vp |
375| endMargin   | [Length](ts-types.md#length)             | 否    | 分割线与侧边栏底端的距离(不支持百分比设置)。<br/>默认值:0.0<br/>单位:vp |
376
377## BarGridColumnOptions<sup>10+</sup>对象说明
378
379TabBar栅格化方式设置的对象,包括栅格模式下的column边距和间隔,以及小、中、大屏下,页签占用的columns数量。
380
381**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
382
383**系统能力:** SystemCapability.ArkUI.ArkUI.Full
384
385| 名称          | 类型                                     | 必填   | 说明                                       |
386| ----------- | ---------------------------------------- | ---- | ---------------------------------------- |
387| margin | [Dimension](ts-types.md#dimension10)             | 否    | 栅格模式下的column边距(不支持百分比设置)。<br/>默认值:24.0<br/>单位:vp                        |
388| gutter      | [Dimension](ts-types.md#dimension10) | 否    | 栅格模式下的column间隔(不支持百分比设置)。<br/>默认值:24.0<br/>单位:vp                     |
389| sm | number            | 否    | 小屏下,页签占用的columns数量,必须是非负偶数。小屏为大于等于320vp但小于600vp。<br/>默认值为-1,代表页签占用TabBar全部宽度。 |
390| md   | number          | 否    | 中屏下,页签占用的columns数量,必须是非负偶数。中屏为大于等于600vp但小于800vp。<br/>默认值为-1,代表页签占用TabBar全部宽度。 |
391| lg   | number           | 否    | 大屏下,页签占用的columns数量,必须是非负偶数。大屏为大于等于840vp但小于1024vp。<br/>默认值为-1,代表页签占用TabBar全部宽度。 |
392
393## ScrollableBarModeOptions<sup>10+</sup>对象说明
394
395Scrollable模式下的TabBar的布局样式对象。
396
397**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
398
399**系统能力:** SystemCapability.ArkUI.ArkUI.Full
400
401| 名称          | 类型                                     | 必填   | 说明                                       |
402| ----------- | ---------------------------------------- | ---- | ---------------------------------------- |
403| margin | [Dimension](ts-types.md#dimension10)          | 否    | Scrollable模式下的TabBar的左右边距(不支持百分比设置)。<br/>默认值:0.0<br/>单位:vp                    |
404| nonScrollableLayoutStyle      | [LayoutStyle](#layoutstyle10枚举说明) | 否    | Scrollable模式下不滚动时的页签排布方式。<br/>默认值:LayoutStyle.ALWAYS_CENTER           |
405
406## BarMode枚举说明
407
408TabBar布局模式枚举。
409
410**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
411
412**系统能力:** SystemCapability.ArkUI.ArkUI.Full
413
414| 名称        | 值 | 说明                                     |
415| ---------- | -- | ---------------------------------------- |
416| Scrollable | 0  | 每一个TabBar均使用实际布局宽度,超过总长度(横向Tabs的barWidth,纵向Tabs的barHeight)后可滑动。 |
417| Fixed      | 1  | 所有TabBar平均分配barWidth宽度(纵向时平均分配barHeight高度)。 |
418
419## AnimationMode<sup>12+</sup>枚举说明
420
421点击TabBar页签时切换TabContent的动画形式枚举。
422
423**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
424
425**系统能力:** SystemCapability.ArkUI.ArkUI.Full
426
427| 名称          | 值   | 说明                                                         |
428| ------------- | ---- | ------------------------------------------------------------ |
429| CONTENT_FIRST | 0    | 先加载目标页内容,再开始切换动画                             |
430| ACTION_FIRST  | 1    | 先开始切换动画,再加载目标页内容;生效需要同时需要满足:Tabs的height、width没有设置成auto |
431| NO_ANIMATION  | 2    | 关闭默认动画                                                 |
432
433## LayoutStyle<sup>10+</sup>枚举说明
434
435Scrollable模式下不滚动时的页签排布方式枚举。
436
437**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
438
439**系统能力:** SystemCapability.ArkUI.ArkUI.Full
440
441| 名称         | 值 | 说明                                     |
442| ---------- | -- | ---------------------------------------- |
443| ALWAYS_CENTER | 0 | 当页签内容超过TabBar宽度时,TabBar可滚动。<br/>当页签内容不超过TabBar宽度时,TabBar不可滚动,页签紧凑居中。|
444| ALWAYS_AVERAGE_SPLIT | 1 | 当页签内容超过TabBar宽度时,TabBar可滚动。<br/>当页签内容不超过TabBar宽度时,TabBar不可滚动,且所有页签平均分配TabBar宽度。|
445| SPACE_BETWEEN_OR_CENTER      | 2 | 当页签内容超过TabBar宽度时,TabBar可滚动。<br/>当页签内容不超过TabBar宽度但超过TabBar宽度一半时,TabBar不可滚动,页签紧凑居中。<br/>当页签内容不超过TabBar宽度一半时,TabBar不可滚动,保证页签居中排列在TabBar宽度一半,且间距相同。|
446
447## 事件
448
449除支持[通用事件](ts-universal-events-click.md)外,还支持以下事件:
450
451### onChange
452
453onChange(event:&nbsp;(index:&nbsp;number)&nbsp;=&gt;&nbsp;void)
454
455Tab页签切换后触发的事件。
456
457触发该事件的条件:
458
4591、TabContent支持滑动时,组件触发滑动时触发。
460
4612、通过[控制器](#tabscontroller)API接口调用。
462
4633、通过[状态变量](../../../quick-start/arkts-state.md)构造的属性值进行修改。
464
4654、通过页签处点击触发。
466
467**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
468
469**系统能力:** SystemCapability.ArkUI.ArkUI.Full
470
471**参数:** 
472
473| 参数名 | 类型   | 必填 | 说明                                   |
474| ------ | ------ | ---- | -------------------------------------- |
475| index  | number | 是   | 当前显示的index索引,索引从0开始计算。 |
476
477### onTabBarClick<sup>10+</sup>
478
479onTabBarClick(event:&nbsp;(index:&nbsp;number)&nbsp;=&gt;&nbsp;void)
480
481Tab页签点击后触发的事件。
482
483**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
484
485**系统能力:** SystemCapability.ArkUI.ArkUI.Full
486
487**参数:** 
488
489| 参数名 | 类型   | 必填 | 说明                                 |
490| ------ | ------ | ---- | ------------------------------------ |
491| index  | number | 是   | 被点击的index索引,索引从0开始计算。 |
492
493### onAnimationStart<sup>11+</sup>
494
495onAnimationStart(handler: (index: number, targetIndex: number, event: TabsAnimationEvent) => void)
496
497切换动画开始时触发该回调。参数为动画开始前的index值(不是最终结束动画的index值)。当animationDuration为0时动画关闭,不触发该回调。
498
499**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
500
501**系统能力:** SystemCapability.ArkUI.ArkUI.Full
502
503**参数:** 
504
505| 参数名      | 类型                                                   | 必填 | 说明                                                         |
506| ----------- | ------------------------------------------------------ | ---- | ------------------------------------------------------------ |
507| index       | number                                                 | 是   | 当前显示元素的索引。                                         |
508| targetIndex | number                                                 | 是   | 切换动画目标元素的索引。                                     |
509| event       | [TabsAnimationEvent](#tabsanimationevent11对象说明) | 是   | 动画相关信息,包括主轴方向上当前显示元素和目标元素相对Tabs起始位置的位移,以及离手速度。 |
510
511### onAnimationEnd<sup>11+</sup>
512
513onAnimationEnd(handler: (index: number, event: TabsAnimationEvent) => void)
514
515切换动画结束时触发该回调。当Tabs切换动效结束时触发,包括动画过程中手势中断。参数为动画结束后的index值。当animationDuration为0时动画关闭,不触发该回调。
516
517**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
518
519**系统能力:** SystemCapability.ArkUI.ArkUI.Full
520
521**参数:** 
522
523| 参数名 | 类型                                                   | 必填 | 说明                                                         |
524| ------ | ------------------------------------------------------ | ---- | ------------------------------------------------------------ |
525| index  | number                                                 | 是   | 当前显示元素的索引。                                         |
526| event  | [TabsAnimationEvent](#tabsanimationevent11对象说明) | 是   | 动画相关信息,只返回主轴方向上当前显示元素相对于Tabs起始位置的位移。 |
527
528### onGestureSwipe<sup>11+</sup>
529
530onGestureSwipe(handler: (index: number, event: TabsAnimationEvent) => void)
531
532在页面跟手滑动过程中,逐帧触发该回调。
533
534**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
535
536**系统能力:** SystemCapability.ArkUI.ArkUI.Full
537
538**参数:** 
539
540| 参数名 | 类型                                                   | 必填 | 说明                                                         |
541| ------ | ------------------------------------------------------ | ---- | ------------------------------------------------------------ |
542| index  | number                                                 | 是   | 当前显示元素的索引。                                         |
543| event  | [TabsAnimationEvent](#tabsanimationevent11对象说明) | 是   | 动画相关信息,只返回主轴方向上当前显示元素相对于Tabs起始位置的位移。 |
544
545### customContentTransition<sup>11+</sup>
546
547customContentTransition(delegate: (from: number, to: number) => TabContentAnimatedTransition \| undefined)
548
549自定义Tabs页面切换动画。
550
551使用说明:
552
5531、当使用自定义切换动画时,Tabs组件自带的默认切换动画会被禁用,同时,页面也无法跟手滑动。<br>2、当设置为undefined时,表示不使用自定义切换动画,仍然使用组件自带的默认切换动画。<br>3、当前自定义切换动画不支持打断。<br>4、目前自定义切换动画只支持两种场景触发:点击页签和调用TabsController.changeIndex()接口。<br>5、当使用自定义切换动画时,Tabs组件支持的事件中,除了onGestureSwipe,其他事件均支持。<br>6、onChange和onAnimationEnd事件的触发时机需要特殊说明:如果在第一次自定义动画执行过程中,触发了第二次自定义动画,那么在开始第二次自定义动画时,就会触发第一次自定义动画的onChange和onAnimationEnd事件。<br>7、当使用自定义动画时,参与动画的页面布局方式会改为Stack布局。如果开发者未主动设置相关页面的zIndex属性,那么所有页面的zIndex值是一样的,页面的渲染层级会按照在组件树上的顺序(即页面的index值顺序)确定。因此,开发者需要主动修改页面的zIndex属性,来控制页面的渲染层级。
554
555**卡片能力:** 从API version 11开始,该接口支持在ArkTS卡片中使用。
556
557**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
558
559**系统能力:** SystemCapability.ArkUI.ArkUI.Full
560
561**参数:** 
562
563| 参数名 | 类型   | 必填 | 说明                            |
564| ------ | ------ | ---- | ------------------------------- |
565| from   | number | 是   | 动画开始时,当前页面的index值。 |
566| to     | number | 是   | 动画开始时,目标页面的index值。 |
567
568**返回值:** 
569
570| 类型                                                         | 说明                     |
571| ------------------------------------------------------------ | ------------------------ |
572| [TabContentAnimatedTransition](#tabcontentanimatedtransition11对象说明)&nbsp;\|&nbsp;undefined | 自定义切换动画相关信息。 |
573
574### onContentWillChange<sup>12+</sup>
575
576onContentWillChange(handler: (currentIndex: number, comingIndex: number) => boolean)
577
578自定义Tabs页面切换拦截事件能力,新页面即将显示时触发该回调。
579
580触发该回调的条件:
581
5821、TabContent支持滑动时,滑动组件切换新页面时触发。
583
5842、通过TabsController.changeIndex接口切换新页面时触发。
585
5863、通过动态修改index属性值切换新页面时触发。
587
5884、通过点击TabBar页签切换新页面时触发。
589
5905、TabBar页签获焦后,通过键盘左右方向键等切换新页面时触发。
591
592**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
593
594**系统能力:** SystemCapability.ArkUI.ArkUI.Full
595
596**参数:** 
597
598| 参数名       | 类型   | 必填 | 说明                                       |
599| ------------ | ------ | ---- | ------------------------------------------ |
600| currentIndex | number | 是   | 当前显示页面的index索引,索引从0开始计算。 |
601| comingIndex  | number | 是   | 将要显示的新页面的index索引。              |
602
603**返回值:** 
604
605| 类型    | 说明                                                         |
606| ------- | ------------------------------------------------------------ |
607| boolean | 当回调函数handler的返回值为true时,Tabs可以切换到新页面。<br/>当回调函数handler的返回值为false时,Tabs无法切换到新页面,仍然显示原来页面内容。 |
608
609## TabsAnimationEvent<sup>11+</sup>对象说明
610
611Tabs组件动画相关信息集合。
612
613**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
614
615**系统能力:** SystemCapability.ArkUI.ArkUI.Full
616
617| 名称            | 类型      | 只读 | 可选 | 说明                                       |
618| ------------- | ---------- | ---- | ---- | ------------------------ |
619| currentOffset | number | 否 | 否 | Tabs当前显示元素在主轴方向上,相对于Tabs起始位置的位移。单位VP,默认值为0。|
620| targetOffset | number | 否 | 否 | Tabs动画目标元素在主轴方向上,相对于Tabs起始位置的位移。单位VP,默认值为0。|
621| velocity | number | 否 | 否 | Tabs离手动画开始时的离手速度。单位VP/S,默认值为0。|
622
623## TabContentAnimatedTransition<sup>11+</sup>对象说明
624
625Tabs自定义切换动画相关信息。
626
627**卡片能力:** 从API version 11开始,该接口支持在ArkTS卡片中使用。
628
629**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
630
631**系统能力:** SystemCapability.ArkUI.ArkUI.Full
632
633| 名称            | 类型         | 必填   | 说明                                       |
634| ------------- | ---------------------- | ---- |---------------------- |
635| timeout | number | 否 | Tabs自定义切换动画超时时间。从自定义动画开始切换计时,如果到达该时间后,开发者仍未调用[TabContentTransitionProxy](#tabcontenttransitionproxy11对象说明)的finishTransition接口通知Tabs组件自定义动画结束,那么组件就会认为此次自定义动画已结束,直接执行后续操作。单位ms,默认值为1000.|
636| transition | (proxy: [TabContentTransitionProxy](#tabcontenttransitionproxy11对象说明)) => void | 是 | 自定义切换动画具体内容。|
637
638## TabContentTransitionProxy<sup>11+</sup>对象说明
639
640Tabs自定义切换动画执行过程中,返回给开发者的proxy对象。开发者可通过该对象获取自定义动画的起始和目标页面信息,同时,也可以通过调用该对象的finishTransition接口通知Tabs组件自定义动画已结束。
641
642**卡片能力:** 从API version 11开始,该接口支持在ArkTS卡片中使用。
643
644**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
645
646**系统能力:** SystemCapability.ArkUI.ArkUI.Full
647
648### 属性
649
650| 名称  | 类型     | 只读 | 可选 | 说明                         |
651| ----- | ------- | ---- | ---- | --------------------------- |
652| from | number | 否 | 否 | 自定义动画起始页面对应的index值。|
653| to | number | 否 | 否 | 自定义动画目标页面对应的index值。|
654
655### finishTransition
656
657finishTransition(): void
658
659通知Tabs组件,此页面的自定义动画已结束。
660
661**卡片能力:** 从API version 11开始,该接口支持在ArkTS卡片中使用。
662
663**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
664
665**系统能力:** SystemCapability.ArkUI.ArkUI.Full
666
667## TabsController
668
669Tabs组件的控制器,用于控制Tabs组件进行页签切换。不支持一个TabsController控制多个Tabs组件。
670
671**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
672
673**系统能力:** SystemCapability.ArkUI.ArkUI.Full
674
675### 导入对象
676
677```ts
678let controller: TabsController = new TabsController()
679```
680
681### constructor
682
683constructor()
684
685TabsController的构造函数。
686
687**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
688
689**系统能力:** SystemCapability.ArkUI.ArkUI.Full
690
691### changeIndex
692
693changeIndex(value: number): void
694
695控制Tabs切换到指定页签。
696
697**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
698
699**系统能力:** SystemCapability.ArkUI.ArkUI.Full
700
701**参数:**
702
703| 参数名   | 类型   | 必填   | 说明                                     |
704| ----- | ------ | ---- | ---------------------------------------- |
705| value | number | 是    | 页签在Tabs里的索引值,索引值从0开始。<br/>**说明:** <br/>设置小于0或大于最大数量的值时,取默认值0。 |
706
707### preloadItems<sup>12+</sup>
708
709preloadItems(indices: Optional\<Array\<number>>): Promise\<void>
710
711控制Tabs预加载指定子节点。调用该接口后会一次性加载所有指定的子节点,因此为了性能考虑,建议分批加载子节点。
712
713**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
714
715**系统能力:** SystemCapability.ArkUI.ArkUI.Full
716
717**参数:**
718
719| 参数名   | 类型   | 必填   | 说明                                     |
720| ----- | ------ | ---- | ---------------------------------------- |
721| indices | Optional\<Array\<number>> | 是 | 需预加载的子节点的下标数组。<br/>默认值:空数组。 |
722
723**返回值:** 
724
725| 类型                                                         | 说明                     |
726| ------------------------------------------------------------ | ------------------------ |
727| Promise\<void> | 预加载完成后触发的回调。 |
728
729**错误码:**
730
731以下错误码的详细介绍请参见[通用错误码](../../errorcode-universal.md)错误码。
732
733| 错误码ID   | 错误信息                                      |
734| --------   | -------------------------------------------- |
735| 401 | Parameter invalid. Possible causes: 1. The parameter type is not Array\<number>; 2. The parameter is an empty array; 3. The parameter contains an invalid index. |
736
737### setTabBarTranslate<sup>14+</sup>
738
739setTabBarTranslate(translate: TranslateOptions): void
740
741设置TabBar的平移距离。
742
743> **说明:**
744>
745> 当使用bindTabsToScrollable或bindTabsToNestedScrollable等接口绑定了Tabs组件和可滚动容器组件后,在滑动可滚动容器组件时,会触发所有与其绑定的Tabs组件的TabBar的显示和隐藏动效,调用setTabBarTranslate接口设置的TabBar平移距离会失效。因此不建议同时使用bindTabsToScrollable、bindTabsToNestedScrollable和setTabBarTranslate接口。
746>
747
748**原子化服务API:** 从API version 14开始,该接口支持在原子化服务中使用。
749
750**系统能力:** SystemCapability.ArkUI.ArkUI.Full
751
752**参数:**
753
754| 参数名   | 类型   | 必填   | 说明                                     |
755| ----- | ------ | ---- | ---------------------------------------- |
756| translate | [TranslateOptions](ts-universal-attributes-transformation.md#translateoptions对象说明) | 是 | 设置TabBar的平移距离。 |
757
758### setTabBarOpacity<sup>14+</sup>
759
760setTabBarOpacity(opacity: number): void
761
762设置TabBar的不透明度。
763
764> **说明:**
765>
766> 当使用bindTabsToScrollable或bindTabsToNestedScrollable等接口绑定了Tabs组件和可滚动容器组件后,在滑动可滚动容器组件时,会触发所有与其绑定的Tabs组件的TabBar的显示和隐藏动效,调用setTabBarOpacity接口设置的TabBar不透明度会失效。因此不建议同时使用bindTabsToScrollable、bindTabsToNestedScrollable和setTabBarOpacity接口。
767>
768
769**原子化服务API:** 从API version 14开始,该接口支持在原子化服务中使用。
770
771**系统能力:** SystemCapability.ArkUI.ArkUI.Full
772
773**参数:**
774
775| 参数名   | 类型   | 必填   | 说明                                     |
776| ----- | ------ | ---- | ---------------------------------------- |
777| opacity | number | 是 | 设置TabBar的不透明度,取值范围为[0.0, 1.0]。 |
778
779## 示例
780
781### 示例1
782
783本示例通过onChange实现切换时自定义tabBar和TabContent的联动。
784
785```ts
786// xxx.ets
787@Entry
788@Component
789struct TabsExample {
790  @State fontColor: string = '#182431'
791  @State selectedFontColor: string = '#007DFF'
792  @State currentIndex: number = 0
793  @State selectedIndex: number = 0
794  private controller: TabsController = new TabsController()
795
796  @Builder tabBuilder(index: number, name: string) {
797    Column() {
798      Text(name)
799        .fontColor(this.selectedIndex === index ? this.selectedFontColor : this.fontColor)
800        .fontSize(16)
801        .fontWeight(this.selectedIndex === index ? 500 : 400)
802        .lineHeight(22)
803        .margin({ top: 17, bottom: 7 })
804      Divider()
805        .strokeWidth(2)
806        .color('#007DFF')
807        .opacity(this.selectedIndex === index ? 1 : 0)
808    }.width('100%')
809  }
810
811  build() {
812    Column() {
813      Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {
814        TabContent() {
815          Column().width('100%').height('100%').backgroundColor('#00CB87')
816        }.tabBar(this.tabBuilder(0, 'green'))
817
818        TabContent() {
819          Column().width('100%').height('100%').backgroundColor('#007DFF')
820        }.tabBar(this.tabBuilder(1, 'blue'))
821
822        TabContent() {
823          Column().width('100%').height('100%').backgroundColor('#FFBF00')
824        }.tabBar(this.tabBuilder(2, 'yellow'))
825
826        TabContent() {
827          Column().width('100%').height('100%').backgroundColor('#E67C92')
828        }.tabBar(this.tabBuilder(3, 'pink'))
829      }
830      .vertical(false)
831      .barMode(BarMode.Fixed)
832      .barWidth(360)
833      .barHeight(56)
834      .animationDuration(400)
835      .onChange((index: number) => {
836        // currentIndex控制TabContent显示页签
837        this.currentIndex = index
838      })
839      .onAnimationStart((index: number, targetIndex: number, event: TabsAnimationEvent) => {
840        if (index === targetIndex) {
841          return
842        }
843        // selectedIndex控制自定义TabBar内Image和Text颜色切换
844        this.selectedIndex = targetIndex
845      })
846      .width(360)
847      .height(296)
848      .margin({ top: 52 })
849      .backgroundColor('#F1F3F5')
850    }.width('100%')
851  }
852}
853```
854
855![tabs2](figures/tabs2.gif)
856
857### 示例2
858
859本示例通过divider实现了分割线各种属性的展示。
860
861```ts
862// xxx.ets
863@Entry
864@Component
865struct TabsDivider1 {
866  private controller1: TabsController = new TabsController()
867  @State dividerColor: string = 'red'
868  @State strokeWidth: number = 2
869  @State startMargin: number = 0
870  @State endMargin: number = 0
871  @State nullFlag: boolean = false
872
873  build() {
874    Column() {
875      Tabs({ controller: this.controller1 }) {
876        TabContent() {
877          Column().width('100%').height('100%').backgroundColor(Color.Pink)
878        }.tabBar('pink')
879
880        TabContent() {
881          Column().width('100%').height('100%').backgroundColor(Color.Yellow)
882        }.tabBar('yellow')
883
884        TabContent() {
885          Column().width('100%').height('100%').backgroundColor(Color.Blue)
886        }.tabBar('blue')
887
888        TabContent() {
889          Column().width('100%').height('100%').backgroundColor(Color.Green)
890        }.tabBar('green')
891
892        TabContent() {
893          Column().width('100%').height('100%').backgroundColor(Color.Red)
894        }.tabBar('red')
895      }
896      .vertical(true)
897      .scrollable(true)
898      .barMode(BarMode.Fixed)
899      .barWidth(70)
900      .barHeight(200)
901      .animationDuration(400)
902      .onChange((index: number) => {
903        console.info(index.toString())
904      })
905      .height('200vp')
906      .margin({ bottom: '12vp' })
907      .divider(this.nullFlag ? null : {
908        strokeWidth: this.strokeWidth,
909        color: this.dividerColor,
910        startMargin: this.startMargin,
911        endMargin: this.endMargin
912      })
913
914      Button('常规Divider').width('100%').margin({ bottom: '12vp' })
915        .onClick(() => {
916          this.nullFlag = false;
917          this.strokeWidth = 2;
918          this.dividerColor = 'red';
919          this.startMargin = 0;
920          this.endMargin = 0;
921        })
922      Button('空Divider').width('100%').margin({ bottom: '12vp' })
923        .onClick(() => {
924          this.nullFlag = true
925        })
926      Button('颜色变为蓝色').width('100%').margin({ bottom: '12vp' })
927        .onClick(() => {
928          this.dividerColor = 'blue'
929        })
930      Button('宽度增加').width('100%').margin({ bottom: '12vp' })
931        .onClick(() => {
932          this.strokeWidth += 2
933        })
934      Button('宽度减小').width('100%').margin({ bottom: '12vp' })
935        .onClick(() => {
936          if (this.strokeWidth > 2) {
937            this.strokeWidth -= 2
938          }
939        })
940      Button('上边距增加').width('100%').margin({ bottom: '12vp' })
941        .onClick(() => {
942          this.startMargin += 2
943        })
944      Button('上边距减少').width('100%').margin({ bottom: '12vp' })
945        .onClick(() => {
946          if (this.startMargin > 2) {
947            this.startMargin -= 2
948          }
949        })
950      Button('下边距增加').width('100%').margin({ bottom: '12vp' })
951        .onClick(() => {
952          this.endMargin += 2
953        })
954      Button('下边距减少').width('100%').margin({ bottom: '12vp' })
955        .onClick(() => {
956          if (this.endMargin > 2) {
957            this.endMargin -= 2
958          }
959        })
960    }.padding({ top: '24vp', left: '24vp', right: '24vp' })
961  }
962}
963```
964
965![tabs3](figures/tabs3.gif)
966
967### 示例3
968
969本示例通过fadingEdge实现了切换子页签渐隐和不渐隐。
970
971```ts
972// xxx.ets
973@Entry
974@Component
975struct TabsOpaque {
976  @State message: string = 'Hello World'
977  private controller: TabsController = new TabsController()
978  private controller1: TabsController = new TabsController()
979  @State selfFadingFade: boolean = true;
980
981  build() {
982    Column() {
983      Button('子页签设置渐隐').width('100%').margin({ bottom: '12vp' })
984        .onClick((event?: ClickEvent) => {
985          this.selfFadingFade = true;
986        })
987      Button('子页签设置不渐隐').width('100%').margin({ bottom: '12vp' })
988        .onClick((event?: ClickEvent) => {
989          this.selfFadingFade = false;
990        })
991      Tabs({ barPosition: BarPosition.End, controller: this.controller }) {
992        TabContent() {
993          Column().width('100%').height('100%').backgroundColor(Color.Pink)
994        }.tabBar('pink')
995
996        TabContent() {
997          Column().width('100%').height('100%').backgroundColor(Color.Yellow)
998        }.tabBar('yellow')
999
1000        TabContent() {
1001          Column().width('100%').height('100%').backgroundColor(Color.Blue)
1002        }.tabBar('blue')
1003
1004        TabContent() {
1005          Column().width('100%').height('100%').backgroundColor(Color.Green)
1006        }.tabBar('green')
1007
1008        TabContent() {
1009          Column().width('100%').height('100%').backgroundColor(Color.Green)
1010        }.tabBar('green')
1011
1012        TabContent() {
1013          Column().width('100%').height('100%').backgroundColor(Color.Green)
1014        }.tabBar('green')
1015
1016        TabContent() {
1017          Column().width('100%').height('100%').backgroundColor(Color.Green)
1018        }.tabBar('green')
1019
1020        TabContent() {
1021          Column().width('100%').height('100%').backgroundColor(Color.Green)
1022        }.tabBar('green')
1023      }
1024      .vertical(false)
1025      .scrollable(true)
1026      .barMode(BarMode.Scrollable)
1027      .barHeight(80)
1028      .animationDuration(400)
1029      .onChange((index: number) => {
1030        console.info(index.toString())
1031      })
1032      .fadingEdge(this.selfFadingFade)
1033      .height('30%')
1034      .width('100%')
1035
1036      Tabs({ barPosition: BarPosition.Start, controller: this.controller1 }) {
1037        TabContent() {
1038          Column().width('100%').height('100%').backgroundColor(Color.Pink)
1039        }.tabBar('pink')
1040
1041        TabContent() {
1042          Column().width('100%').height('100%').backgroundColor(Color.Yellow)
1043        }.tabBar('yellow')
1044
1045        TabContent() {
1046          Column().width('100%').height('100%').backgroundColor(Color.Blue)
1047        }.tabBar('blue')
1048
1049        TabContent() {
1050          Column().width('100%').height('100%').backgroundColor(Color.Green)
1051        }.tabBar('green')
1052
1053        TabContent() {
1054          Column().width('100%').height('100%').backgroundColor(Color.Green)
1055        }.tabBar('green')
1056
1057        TabContent() {
1058          Column().width('100%').height('100%').backgroundColor(Color.Green)
1059        }.tabBar('green')
1060      }
1061      .vertical(true)
1062      .scrollable(true)
1063      .barMode(BarMode.Scrollable)
1064      .barHeight(200)
1065      .barWidth(80)
1066      .animationDuration(400)
1067      .onChange((index: number) => {
1068        console.info(index.toString())
1069      })
1070      .fadingEdge(this.selfFadingFade)
1071      .height('30%')
1072      .width('100%')
1073    }
1074    .padding({ top: '24vp', left: '24vp', right: '24vp' })
1075  }
1076}
1077```
1078
1079![tabs4](figures/tabs4.gif)
1080
1081### 示例4
1082
1083本示例通过barOverlap实现了TabBar是否背后变模糊并叠加在TabContent之上。
1084
1085```ts
1086// xxx.ets
1087@Entry
1088@Component
1089struct barBackgroundColorTest {
1090  private controller: TabsController = new TabsController()
1091  @State barOverlap: boolean = true;
1092  @State barBackgroundColor: string = '#88888888';
1093
1094  build() {
1095    Column() {
1096      Button("barOverlap变化").width('100%').margin({ bottom: '12vp' })
1097        .onClick((event?: ClickEvent) => {
1098          if (this.barOverlap) {
1099            this.barOverlap = false;
1100          } else {
1101            this.barOverlap = true;
1102          }
1103        })
1104
1105      Tabs({ barPosition: BarPosition.Start, index: 0, controller: this.controller }) {
1106        TabContent() {
1107          Column() {
1108            Text(`barOverlap ${this.barOverlap}`).fontSize(16).margin({ top: this.barOverlap ? '56vp' : 0 })
1109            Text(`barBackgroundColor ${this.barBackgroundColor}`).fontSize(16)
1110          }.width('100%').width('100%').height('100%')
1111          .backgroundColor(Color.Pink)
1112        }
1113        .tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), "1"))
1114
1115        TabContent() {
1116          Column() {
1117            Text(`barOverlap ${this.barOverlap}`).fontSize(16).margin({ top: this.barOverlap ? '56vp' : 0 })
1118            Text(`barBackgroundColor ${this.barBackgroundColor}`).fontSize(16)
1119          }.width('100%').width('100%').height('100%')
1120          .backgroundColor(Color.Yellow)
1121        }
1122        .tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), "2"))
1123
1124        TabContent() {
1125          Column() {
1126            Text(`barOverlap ${this.barOverlap}`).fontSize(16).margin({ top: this.barOverlap ? '56vp' : 0 })
1127            Text(`barBackgroundColor ${this.barBackgroundColor}`).fontSize(16)
1128          }.width('100%').width('100%').height('100%')
1129          .backgroundColor(Color.Green)
1130        }
1131        .tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), "3"))
1132      }
1133      .vertical(false)
1134      .barMode(BarMode.Fixed)
1135      .height('60%')
1136      .barOverlap(this.barOverlap)
1137      .scrollable(true)
1138      .animationDuration(10)
1139      .barBackgroundColor(this.barBackgroundColor)
1140    }
1141    .height(500)
1142    .padding({ top: '24vp', left: '24vp', right: '24vp' })
1143  }
1144}
1145```
1146
1147![tabs5](figures/tabs5.gif)
1148
1149### 示例5
1150
1151本示例通过barGridAlign实现了以栅格化方式设置TabBar的可见区域。
1152
1153```ts
1154// xxx.ets
1155@Entry
1156@Component
1157struct TabsExample5 {
1158  private controller: TabsController = new TabsController()
1159  @State gridMargin: number = 10
1160  @State gridGutter: number = 10
1161  @State sm: number = -2
1162  @State clickedContent: string = "";
1163
1164  build() {
1165    Column() {
1166      Row() {
1167        Button("gridMargin+10 " + this.gridMargin)
1168          .width('47%')
1169          .height(50)
1170          .margin({ top: 5 })
1171          .onClick((event?: ClickEvent) => {
1172            this.gridMargin += 10
1173          })
1174          .margin({ right: '6%', bottom: '12vp' })
1175        Button("gridMargin-10 " + this.gridMargin)
1176          .width('47%')
1177          .height(50)
1178          .margin({ top: 5 })
1179          .onClick((event?: ClickEvent) => {
1180            this.gridMargin -= 10
1181          })
1182          .margin({ bottom: '12vp' })
1183      }
1184
1185      Row() {
1186        Button("gridGutter+10 " + this.gridGutter)
1187          .width('47%')
1188          .height(50)
1189          .margin({ top: 5 })
1190          .onClick((event?: ClickEvent) => {
1191            this.gridGutter += 10
1192          })
1193          .margin({ right: '6%', bottom: '12vp' })
1194        Button("gridGutter-10 " + this.gridGutter)
1195          .width('47%')
1196          .height(50)
1197          .margin({ top: 5 })
1198          .onClick((event?: ClickEvent) => {
1199            this.gridGutter -= 10
1200          })
1201          .margin({ bottom: '12vp' })
1202      }
1203
1204      Row() {
1205        Button("sm+2 " + this.sm)
1206          .width('47%')
1207          .height(50)
1208          .margin({ top: 5 })
1209          .onClick((event?: ClickEvent) => {
1210            this.sm += 2
1211          })
1212          .margin({ right: '6%' })
1213        Button("sm-2 " + this.sm).width('47%').height(50).margin({ top: 5 })
1214          .onClick((event?: ClickEvent) => {
1215            this.sm -= 2
1216          })
1217      }
1218
1219      Text("点击内容:" + this.clickedContent).width('100%').height(200).margin({ top: 5 })
1220
1221
1222      Tabs({ barPosition: BarPosition.End, controller: this.controller }) {
1223        TabContent() {
1224          Column().width('100%').height('100%').backgroundColor(Color.Pink)
1225        }.tabBar(BottomTabBarStyle.of($r("sys.media.ohos_app_icon"), "1"))
1226
1227        TabContent() {
1228          Column().width('100%').height('100%').backgroundColor(Color.Green)
1229        }.tabBar(BottomTabBarStyle.of($r("sys.media.ohos_app_icon"), "2"))
1230
1231        TabContent() {
1232          Column().width('100%').height('100%').backgroundColor(Color.Blue)
1233        }.tabBar(BottomTabBarStyle.of($r("sys.media.ohos_app_icon"), "3"))
1234      }
1235      .width('350vp')
1236      .animationDuration(300)
1237      .height('60%')
1238      .barGridAlign({ sm: this.sm, margin: this.gridMargin, gutter: this.gridGutter })
1239      .backgroundColor(0xf1f3f5)
1240      .onTabBarClick((index: number) => {
1241        this.clickedContent += "now index " + index + " is clicked\n";
1242      })
1243    }
1244    .width('100%')
1245    .height(500)
1246    .margin({ top: 5 })
1247    .padding('10vp')
1248  }
1249}
1250```
1251
1252![tabs5](figures/tabs6.gif)
1253
1254### 示例6
1255
1256本示例实现了barMode的ScrollableBarModeOptions参数,该参数仅在Scrollable模式下有效。
1257
1258```ts
1259// xxx.ets
1260@Entry
1261@Component
1262struct TabsExample6 {
1263  private controller: TabsController = new TabsController()
1264  @State scrollMargin: number = 0
1265  @State layoutStyle: LayoutStyle = LayoutStyle.ALWAYS_CENTER
1266  @State text: string = "文本"
1267
1268  build() {
1269    Column() {
1270      Row() {
1271        Button("scrollMargin+10 " + this.scrollMargin)
1272          .width('47%')
1273          .height(50)
1274          .margin({ top: 5 })
1275          .onClick((event?: ClickEvent) => {
1276            this.scrollMargin += 10
1277          })
1278          .margin({ right: '6%', bottom: '12vp' })
1279        Button("scrollMargin-10 " + this.scrollMargin)
1280          .width('47%')
1281          .height(50)
1282          .margin({ top: 5 })
1283          .onClick((event?: ClickEvent) => {
1284            this.scrollMargin -= 10
1285          })
1286          .margin({ bottom: '12vp' })
1287      }
1288
1289      Row() {
1290        Button("文本增加 ")
1291          .width('47%')
1292          .height(50)
1293          .margin({ top: 5 })
1294          .onClick((event?: ClickEvent) => {
1295            this.text += '文本增加'
1296          })
1297          .margin({ right: '6%', bottom: '12vp' })
1298        Button("文本重置")
1299          .width('47%')
1300          .height(50)
1301          .margin({ top: 5 })
1302          .onClick((event?: ClickEvent) => {
1303            this.text = "文本"
1304          })
1305          .margin({ bottom: '12vp' })
1306      }
1307
1308      Row() {
1309        Button("layoutStyle.ALWAYS_CENTER")
1310          .width('100%')
1311          .height(50)
1312          .margin({ top: 5 })
1313          .fontSize(15)
1314          .onClick((event?: ClickEvent) => {
1315            this.layoutStyle = LayoutStyle.ALWAYS_CENTER;
1316          })
1317          .margin({ bottom: '12vp' })
1318      }
1319
1320      Row() {
1321        Button("layoutStyle.ALWAYS_AVERAGE_SPLIT")
1322          .width('100%')
1323          .height(50)
1324          .margin({ top: 5 })
1325          .fontSize(15)
1326          .onClick((event?: ClickEvent) => {
1327            this.layoutStyle = LayoutStyle.ALWAYS_AVERAGE_SPLIT;
1328          })
1329          .margin({ bottom: '12vp' })
1330      }
1331
1332      Row() {
1333        Button("layoutStyle.SPACE_BETWEEN_OR_CENTER")
1334          .width('100%')
1335          .height(50)
1336          .margin({ top: 5 })
1337          .fontSize(15)
1338          .onClick((event?: ClickEvent) => {
1339            this.layoutStyle = LayoutStyle.SPACE_BETWEEN_OR_CENTER;
1340          })
1341          .margin({ bottom: '12vp' })
1342      }
1343
1344      Tabs({ barPosition: BarPosition.End, controller: this.controller }) {
1345        TabContent() {
1346          Column().width('100%').height('100%').backgroundColor(Color.Pink)
1347        }.tabBar(SubTabBarStyle.of(this.text))
1348
1349        TabContent() {
1350          Column().width('100%').height('100%').backgroundColor(Color.Green)
1351        }.tabBar(SubTabBarStyle.of(this.text))
1352
1353        TabContent() {
1354          Column().width('100%').height('100%').backgroundColor(Color.Blue)
1355        }.tabBar(SubTabBarStyle.of(this.text))
1356      }
1357      .animationDuration(300)
1358      .height('60%')
1359      .backgroundColor(0xf1f3f5)
1360      .barMode(BarMode.Scrollable, { margin: this.scrollMargin, nonScrollableLayoutStyle: this.layoutStyle })
1361    }
1362    .width('100%')
1363    .height(500)
1364    .margin({ top: 5 })
1365    .padding('24vp')
1366  }
1367}
1368```
1369
1370![tabs5](figures/tabs7.gif)
1371
1372### 示例7
1373
1374本示例通过customContentTransition实现了自定义Tabs页面的切换动画。
1375
1376```ts
1377// xxx.ets
1378interface itemType {
1379  text: string,
1380  backgroundColor: Color
1381}
1382
1383@Entry
1384@Component
1385struct TabsCustomAnimationExample {
1386  @State data: itemType[] = [
1387    {
1388      text: 'Red',
1389      backgroundColor: Color.Red
1390    },
1391    {
1392      text: 'Yellow',
1393      backgroundColor: Color.Yellow
1394    },
1395    {
1396      text: 'Blue',
1397      backgroundColor: Color.Blue
1398    }]
1399  @State opacityList: number[] = []
1400  @State scaleList: number[] = []
1401
1402  private durationList: number[] = []
1403  private timeoutList: number[] = []
1404  private customContentTransition: (from: number, to: number) => TabContentAnimatedTransition = (from: number, to: number) => {
1405    let tabContentAnimatedTransition = {
1406      timeout: this.timeoutList[from],
1407      transition: (proxy: TabContentTransitionProxy) => {
1408        this.scaleList[from] = 1.0
1409        this.scaleList[to] = 0.5
1410        this.opacityList[from] = 1.0
1411        this.opacityList[to] = 0.5
1412        animateTo({
1413          duration: this.durationList[from],
1414          onFinish: () => {
1415            proxy.finishTransition()
1416          }
1417        }, () => {
1418          this.scaleList[from] = 0.5
1419          this.scaleList[to] = 1.0
1420          this.opacityList[from] = 0.5
1421          this.opacityList[to] = 1.0
1422        })
1423      }
1424    } as TabContentAnimatedTransition
1425    return tabContentAnimatedTransition
1426  }
1427
1428  aboutToAppear(): void {
1429    let duration = 1000
1430    let timeout = 1000
1431    for (let i = 1; i <= this.data.length; i++) {
1432      this.opacityList.push(1.0)
1433      this.scaleList.push(1.0)
1434      this.durationList.push(duration * i)
1435      this.timeoutList.push(timeout * i)
1436    }
1437  }
1438
1439  build() {
1440    Column() {
1441      Tabs() {
1442        ForEach(this.data, (item: itemType, index: number) => {
1443          TabContent() {}
1444          .tabBar(item.text)
1445          .backgroundColor(item.backgroundColor)
1446          // 自定义动画变化透明度、缩放页面等
1447          .opacity(this.opacityList[index])
1448          .scale({ x: this.scaleList[index], y: this.scaleList[index] })
1449        })
1450      }
1451      .backgroundColor(0xf1f3f5)
1452      .width('100%')
1453      .height(500)
1454      .customContentTransition(this.customContentTransition)
1455    }
1456  }
1457}
1458```
1459
1460![tabs5](figures/tabs8.gif)
1461### 示例8
1462
1463本示例通过onContentWillChange实现了自定义页面手势滑动切换拦截。
1464
1465```ts
1466//xxx.ets
1467@Entry
1468@Component
1469struct TabsExample {
1470  @State currentIndex: number = 2
1471  private controller: TabsController = new TabsController()
1472  @Builder tabBuilder(title: string,targetIndex: number) {
1473    Column(){
1474      Text(title).fontColor(this.currentIndex === targetIndex ? '#1698CE' : '#6B6B6B')
1475    }.width('100%')
1476    .height(50)
1477    .justifyContent(FlexAlign.Center)
1478  }
1479  build() {
1480    Column() {
1481      Tabs({ barPosition: BarPosition.End, controller: this.controller, index: this.currentIndex }) {
1482        TabContent() {
1483          Column(){
1484            Text('首页的内容')
1485          }.width('100%').height('100%').backgroundColor('#00CB87').justifyContent(FlexAlign.Center)
1486        }.tabBar(this.tabBuilder('首页',0))
1487
1488        TabContent() {
1489          Column(){
1490            Text('发现的内容')
1491          }.width('100%').height('100%').backgroundColor('#007DFF').justifyContent(FlexAlign.Center)
1492        }.tabBar(this.tabBuilder('发现',1))
1493
1494        TabContent() {
1495          Column(){
1496            Text('推荐的内容')
1497          }.width('100%').height('100%').backgroundColor('#FFBF00').justifyContent(FlexAlign.Center)
1498        }.tabBar(this.tabBuilder('推荐',2))
1499
1500        TabContent() {
1501          Column(){
1502            Text('我的内容')
1503          }.width('100%').height('100%').backgroundColor('#E67C92').justifyContent(FlexAlign.Center)
1504        }.tabBar(this.tabBuilder('我的',3))
1505      }
1506      .vertical(false)
1507      .barMode(BarMode.Fixed)
1508      .barWidth(360)
1509      .barHeight(60)
1510      .animationDuration(0)
1511      .onChange((index: number) => {
1512        this.currentIndex = index
1513      })
1514      .width(360)
1515      .height(600)
1516      .backgroundColor('#F1F3F5')
1517      .scrollable(true)
1518      .onContentWillChange((currentIndex, comingIndex) => {
1519        if (comingIndex == 2) {
1520          return false
1521        }
1522        return true
1523      })
1524
1525      Button('动态修改index').width('50%').margin({ top: 20 })
1526        .onClick(()=>{
1527          this.currentIndex = (this.currentIndex + 1) % 4
1528        })
1529
1530      Button('changeIndex').width('50%').margin({ top: 20 })
1531        .onClick(()=>{
1532          this.currentIndex = (this.currentIndex + 1) % 4
1533          this.controller.changeIndex(this.currentIndex)
1534        })
1535    }.width('100%')
1536  }
1537}
1538```
1539
1540![tabs9](figures/tabs9.gif)
1541### 示例9
1542
1543本示例通过onChange、onAnimationStart、onAnimationEnd、onGestureSwipe等接口实现了自定义TabBar的切换动画。
1544
1545```ts
1546// xxx.ets
1547@Entry
1548@Component
1549struct TabsExample {
1550  @State currentIndex: number = 0
1551  @State animationDuration: number = 300
1552  @State indicatorLeftMargin: number = 0
1553  @State indicatorWidth: number = 0
1554  private tabsWidth: number = 0
1555  private textInfos: [number, number][] = []
1556  private isStartAnimateTo: boolean = false
1557
1558  @Builder
1559  tabBuilder(index: number, name: string) {
1560    Column() {
1561      Text(name)
1562        .fontSize(16)
1563        .fontColor(this.currentIndex === index ? '#007DFF' : '#182431')
1564        .fontWeight(this.currentIndex === index ? 500 : 400)
1565        .id(index.toString())
1566        .onAreaChange((oldValue: Area, newValue: Area) => {
1567          this.textInfos[index] = [newValue.globalPosition.x as number, newValue.width as number]
1568          if (this.currentIndex === index && !this.isStartAnimateTo) {
1569            this.indicatorLeftMargin = this.textInfos[index][0]
1570            this.indicatorWidth = this.textInfos[index][1]
1571          }
1572        })
1573    }.width('100%')
1574  }
1575
1576  build() {
1577    Stack({ alignContent: Alignment.TopStart }) {
1578      Tabs({ barPosition: BarPosition.Start }) {
1579        TabContent() {
1580          Column().width('100%').height('100%').backgroundColor('#00CB87')
1581        }.tabBar(this.tabBuilder(0, 'green'))
1582
1583        TabContent() {
1584          Column().width('100%').height('100%').backgroundColor('#007DFF')
1585        }.tabBar(this.tabBuilder(1, 'blue'))
1586
1587        TabContent() {
1588          Column().width('100%').height('100%').backgroundColor('#FFBF00')
1589        }.tabBar(this.tabBuilder(2, 'yellow'))
1590
1591        TabContent() {
1592          Column().width('100%').height('100%').backgroundColor('#E67C92')
1593        }.tabBar(this.tabBuilder(3, 'pink'))
1594      }
1595      .onAreaChange((oldValue: Area, newValue: Area)=> {
1596        this.tabsWidth = newValue.width as number
1597      })
1598      .barWidth('100%')
1599      .barHeight(56)
1600      .width('100%')
1601      .height(296)
1602      .backgroundColor('#F1F3F5')
1603      .animationDuration(this.animationDuration)
1604      .onChange((index: number) => {
1605        this.currentIndex = index // 监听索引index的变化,实现页签内容的切换。
1606      })
1607      .onAnimationStart((index: number, targetIndex: number, event: TabsAnimationEvent) => {
1608        // 切换动画开始时触发该回调。下划线跟着页面一起滑动,同时宽度渐变。
1609        this.currentIndex = targetIndex
1610        this.startAnimateTo(this.animationDuration, this.textInfos[targetIndex][0], this.textInfos[targetIndex][1])
1611      })
1612      .onAnimationEnd((index: number, event: TabsAnimationEvent) => {
1613        // 切换动画结束时触发该回调。下划线动画停止。
1614        let currentIndicatorInfo = this.getCurrentIndicatorInfo(index, event)
1615        this.startAnimateTo(0, currentIndicatorInfo.left, currentIndicatorInfo.width)
1616      })
1617      .onGestureSwipe((index: number, event: TabsAnimationEvent) => {
1618        // 在页面跟手滑动过程中,逐帧触发该回调。
1619        let currentIndicatorInfo = this.getCurrentIndicatorInfo(index, event)
1620        this.currentIndex = currentIndicatorInfo.index
1621        this.indicatorLeftMargin = currentIndicatorInfo.left
1622        this.indicatorWidth = currentIndicatorInfo.width
1623      })
1624
1625      Column()
1626        .height(2)
1627        .width(this.indicatorWidth)
1628        .margin({ left: this.indicatorLeftMargin, top:48})
1629        .backgroundColor('#007DFF')
1630    }.width('100%')
1631  }
1632
1633  private getCurrentIndicatorInfo(index: number, event: TabsAnimationEvent): Record<string, number> {
1634    let nextIndex = index
1635    if (index > 0 && event.currentOffset > 0) {
1636      nextIndex--
1637    } else if (index < 3 && event.currentOffset < 0) {
1638      nextIndex++
1639    }
1640    let indexInfo = this.textInfos[index]
1641    let nextIndexInfo = this.textInfos[nextIndex]
1642    let swipeRatio = Math.abs(event.currentOffset / this.tabsWidth)
1643    let currentIndex = swipeRatio > 0.5 ? nextIndex : index // 页面滑动超过一半,tabBar切换到下一页。
1644    let currentLeft = indexInfo[0] + (nextIndexInfo[0] - indexInfo[0]) * swipeRatio
1645    let currentWidth = indexInfo[1] + (nextIndexInfo[1] - indexInfo[1]) * swipeRatio
1646    return { 'index': currentIndex, 'left': currentLeft, 'width': currentWidth }
1647  }
1648
1649  private startAnimateTo(duration: number, leftMargin: number, width: number) {
1650    this.isStartAnimateTo = true
1651    animateTo({
1652      duration: duration, // 动画时长
1653      curve: Curve.Linear, // 动画曲线
1654      iterations: 1, // 播放次数
1655      playMode: PlayMode.Normal, // 动画模式
1656      onFinish: () => {
1657        this.isStartAnimateTo = false
1658        console.info('play end')
1659      }
1660    }, () => {
1661      this.indicatorLeftMargin = leftMargin
1662      this.indicatorWidth = width
1663    })
1664  }
1665}
1666```
1667
1668![tabs10](figures/tabs10.gif)
1669
1670### 示例10
1671
1672本示例通过preloadItems接口实现了预加载指定子节点。
1673
1674```ts
1675// xxx.ets
1676import { BusinessError } from '@kit.BasicServicesKit'
1677
1678@Entry
1679@Component
1680struct TabsPreloadItems {
1681  @State currentIndex: number = 1
1682  private tabsController: TabsController = new TabsController()
1683
1684  build() {
1685    Column() {
1686      Tabs({ index: this.currentIndex, controller: this.tabsController }) {
1687        TabContent() {
1688          MyComponent({ color: '#00CB87' })
1689        }.tabBar(SubTabBarStyle.of('green'))
1690
1691        TabContent() {
1692          MyComponent({ color: '#007DFF' })
1693        }.tabBar(SubTabBarStyle.of('blue'))
1694
1695        TabContent() {
1696          MyComponent({ color: '#FFBF00' })
1697        }.tabBar(SubTabBarStyle.of('yellow'))
1698
1699        TabContent() {
1700          MyComponent({ color: '#E67C92' })
1701        }.tabBar(SubTabBarStyle.of('pink'))
1702      }
1703      .width(360)
1704      .height(296)
1705      .backgroundColor('#F1F3F5')
1706      .onChange((index: number) => {
1707        this.currentIndex = index
1708      })
1709
1710      Button('preload items: [0, 2, 3]')
1711        .margin(5)
1712        .onClick(() => {
1713          // 预加载第0、2、3个子节点,提高滑动或点击切换至这些节点时的性能
1714          this.tabsController.preloadItems([0, 2, 3])
1715            .then(() => {
1716              console.info('preloadItems success.')
1717            })
1718            .catch((error: BusinessError) => {
1719              console.error('preloadItems failed, error code: ' + error.code + ', error message: ' + error.message)
1720            })
1721        })
1722    }
1723  }
1724}
1725
1726@Component
1727struct MyComponent {
1728  private color: string = ""
1729
1730  aboutToAppear(): void {
1731    console.info('aboutToAppear backgroundColor:' + this.color)
1732  }
1733
1734  aboutToDisappear(): void {
1735    console.info('aboutToDisappear backgroundColor:' + this.color)
1736  }
1737
1738  build() {
1739    Column()
1740      .width('100%')
1741      .height('100%')
1742      .backgroundColor(this.color)
1743  }
1744}
1745```
1746
1747### 示例11
1748
1749本示例通过setTabBarTranslate、setTabBarOpacity等接口设置了TabBar的平移距离和不透明度。
1750
1751```ts
1752// xxx.ets
1753@Entry
1754@Component
1755struct TabsExample {
1756  private controller: TabsController = new TabsController()
1757
1758  build() {
1759    Column() {
1760      Button('设置TabBar的平移距离').margin({ top: 20 })
1761        .onClick(() => {
1762          this.controller.setTabBarTranslate({ x: -20, y: -20 })
1763        })
1764
1765      Button('设置TabBar的透明度').margin({ top: 20 })
1766        .onClick(() => {
1767          this.controller.setTabBarOpacity(0.5)
1768        })
1769
1770      Tabs({ barPosition: BarPosition.End, controller: this.controller }) {
1771        TabContent() {
1772          Column().width('100%').height('100%').backgroundColor('#00CB87')
1773        }.tabBar(BottomTabBarStyle.of($r('app.media.startIcon'), 'green'))
1774
1775        TabContent() {
1776          Column().width('100%').height('100%').backgroundColor('#007DFF')
1777        }.tabBar(BottomTabBarStyle.of($r('app.media.startIcon'), 'blue'))
1778
1779        TabContent() {
1780          Column().width('100%').height('100%').backgroundColor('#FFBF00')
1781        }.tabBar(BottomTabBarStyle.of($r('app.media.startIcon'), 'yellow'))
1782
1783        TabContent() {
1784          Column().width('100%').height('100%').backgroundColor('#E67C92')
1785        }.tabBar(BottomTabBarStyle.of($r('app.media.startIcon'), 'pink'))
1786      }
1787      .width(360)
1788      .height(296)
1789      .margin({ top: 20 })
1790      .barBackgroundColor('#F1F3F5')
1791    }
1792    .width('100%')
1793  }
1794}
1795```
1796
1797![tabs11](figures/tabs11.gif)