1e41f4b71Sopenharmony_ci# Tabs 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ciThe **Tabs** component is a container component that allows users to switch between content views through tabs. Each tab page corresponds to a content view. 4e41f4b71Sopenharmony_ci 5e41f4b71Sopenharmony_ci> **NOTE** 6e41f4b71Sopenharmony_ci> 7e41f4b71Sopenharmony_ci> This component is supported since API version 7. Updates will be marked with a superscript to indicate their earliest API version. 8e41f4b71Sopenharmony_ci> 9e41f4b71Sopenharmony_ci> Since API version 11, this component supports the safe area attribute by default, with the default attribute value being **expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM]))**. You can override this attribute to change the default behavior. In earlier versions, you need to use the [expandSafeArea](ts-universal-attributes-expand-safe-area.md) attribute to implement the safe area feature. 10e41f4b71Sopenharmony_ci 11e41f4b71Sopenharmony_ci 12e41f4b71Sopenharmony_ci## Child Components 13e41f4b71Sopenharmony_ci 14e41f4b71Sopenharmony_ciCustom components cannot be used as child components. Only the [TabContent](ts-container-tabcontent.md) child component is allowed, with support for [if/else](../../../quick-start/arkts-rendering-control-ifelse.md) and [ForEach](../../../quick-start/arkts-rendering-control-foreach.md) rendering control. In addition, the **if/else** and **ForEach** statements support **TabContent** components only, but not custom components. 15e41f4b71Sopenharmony_ci 16e41f4b71Sopenharmony_ci> **NOTE** 17e41f4b71Sopenharmony_ci> 18e41f4b71Sopenharmony_ci> If the child component has the **visibility** attribute set to **None** or **Hidden**, it is hidden but takes up space in the layout. 19e41f4b71Sopenharmony_ci 20e41f4b71Sopenharmony_ci 21e41f4b71Sopenharmony_ci## APIs 22e41f4b71Sopenharmony_ci 23e41f4b71Sopenharmony_ciTabs(value?: {barPosition?: BarPosition, index?: number, controller?: TabsController}) 24e41f4b71Sopenharmony_ci 25e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 26e41f4b71Sopenharmony_ci 27e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 28e41f4b71Sopenharmony_ci 29e41f4b71Sopenharmony_ci**Parameters** 30e41f4b71Sopenharmony_ci 31e41f4b71Sopenharmony_ci| Name | Type | Mandatory | Description | 32e41f4b71Sopenharmony_ci| ----------- | --------------------------------- | ---- | ---------------------------------------- | 33e41f4b71Sopenharmony_ci| barPosition | [BarPosition](#barposition)| No | Position of the **Tabs** component.<br>Default value: **BarPosition.Start** | 34e41f4b71Sopenharmony_ci| index | number | No | Index of the currently displayed tab.<br>Default value: **0**<br>**NOTE**<br><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 the tab is switched by changing the index, the tab switching animation does not take effect. When **changeIndex** of **TabController** is used for tab switching, the tab switching animation is enabled by default. You can disable the animation by setting **animationDuration** to **0**.<br>Since API version 10, this parameter supports two-way binding through [$$](../../../quick-start/arkts-two-way-sync.md).| 35e41f4b71Sopenharmony_ci| controller | [TabsController](#tabscontroller) | No | Tab controller. | 36e41f4b71Sopenharmony_ci 37e41f4b71Sopenharmony_ci## BarPosition 38e41f4b71Sopenharmony_ci 39e41f4b71Sopenharmony_ciEnumerates the positions of the **Tabs** component. 40e41f4b71Sopenharmony_ci 41e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 42e41f4b71Sopenharmony_ci 43e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 44e41f4b71Sopenharmony_ci 45e41f4b71Sopenharmony_ci| Name | Description | 46e41f4b71Sopenharmony_ci| ----- | ---------------------------------------- | 47e41f4b71Sopenharmony_ci| 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.| 48e41f4b71Sopenharmony_ci| 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.| 49e41f4b71Sopenharmony_ci 50e41f4b71Sopenharmony_ci 51e41f4b71Sopenharmony_ci## Attributes 52e41f4b71Sopenharmony_ci 53e41f4b71Sopenharmony_ciIn addition to the [universal attributes](ts-universal-attributes-size.md), the following attributes are supported. 54e41f4b71Sopenharmony_ci 55e41f4b71Sopenharmony_ci### vertical 56e41f4b71Sopenharmony_ci 57e41f4b71Sopenharmony_civertical(value: boolean) 58e41f4b71Sopenharmony_ci 59e41f4b71Sopenharmony_ciSets whether to use vertical tabs. 60e41f4b71Sopenharmony_ci 61e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 62e41f4b71Sopenharmony_ci 63e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 64e41f4b71Sopenharmony_ci 65e41f4b71Sopenharmony_ci**Parameters** 66e41f4b71Sopenharmony_ci 67e41f4b71Sopenharmony_ci| Name| Type | Mandatory| Description | 68e41f4b71Sopenharmony_ci| ------ | ------- | ---- | ------------------------------------------------------------ | 69e41f4b71Sopenharmony_ci| value | boolean | Yes | Whether to use vertical tabs.<br>The value **true** means to use vertical tabs, and **false** means to use horizontal tabs.<br>Default value: **false**<br>If set to have a height of **auto**, horizontal tabs auto-adapt the height to child components, which is calculated as follows: Tab bar height + Divider width + Tab content height + Top and bottom paddings + Top and bottom border widths.<br>If set to have a width of **auto**, vertical tabs auto-adapt the width to child components, which is calculated as follows: Tab bar width + Divider width + Tab content width + Left and right paddings + Left and right border widths.<br>To avoid animation jitter when switching between tabs, maintain a consistent size for child components on each tab.| 70e41f4b71Sopenharmony_ci 71e41f4b71Sopenharmony_ci### scrollable 72e41f4b71Sopenharmony_ci 73e41f4b71Sopenharmony_ciscrollable(value: boolean) 74e41f4b71Sopenharmony_ci 75e41f4b71Sopenharmony_ciSets whether the tabs are scrollable. 76e41f4b71Sopenharmony_ci 77e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 78e41f4b71Sopenharmony_ci 79e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 80e41f4b71Sopenharmony_ci 81e41f4b71Sopenharmony_ci**Parameters** 82e41f4b71Sopenharmony_ci 83e41f4b71Sopenharmony_ci| Name| Type | Mandatory| Description | 84e41f4b71Sopenharmony_ci| ------ | ------- | ---- | ------------------------------------------------------------ | 85e41f4b71Sopenharmony_ci| value | boolean | Yes | Whether the tabs are scrollable.<br>**true** (default): The tabs are scrollable.<br> **false**: The tabs are not scrollable.| 86e41f4b71Sopenharmony_ci 87e41f4b71Sopenharmony_ci### barMode 88e41f4b71Sopenharmony_ci 89e41f4b71Sopenharmony_cibarMode(value: BarMode, options?: ScrollableBarModeOptions) 90e41f4b71Sopenharmony_ci 91e41f4b71Sopenharmony_ciSets the tab bar layout mode. 92e41f4b71Sopenharmony_ci 93e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 94e41f4b71Sopenharmony_ci 95e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 96e41f4b71Sopenharmony_ci 97e41f4b71Sopenharmony_ci**Parameters** 98e41f4b71Sopenharmony_ci 99e41f4b71Sopenharmony_ci| Name | Type | Mandatory| Description | 100e41f4b71Sopenharmony_ci| --------------------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | 101e41f4b71Sopenharmony_ci| value | [BarMode](#barmode) | Yes | Layout mode.<br>Default value: **BarMode.Fixed** | 102e41f4b71Sopenharmony_ci| options<sup>10+</sup> | [ScrollableBarModeOptions](#scrollablebarmodeoptions10)| No | Layout style.<br>**NOTE**<br>This value is effective only when the tab bar is in scrollable mode.| 103e41f4b71Sopenharmony_ci 104e41f4b71Sopenharmony_ci### barMode<sup>10+</sup> 105e41f4b71Sopenharmony_ci 106e41f4b71Sopenharmony_cibarMode(value: BarMode.Fixed) 107e41f4b71Sopenharmony_ci 108e41f4b71Sopenharmony_ciSets the tab bar layout mode to **BarMode.Fixed**. 109e41f4b71Sopenharmony_ci 110e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 111e41f4b71Sopenharmony_ci 112e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 113e41f4b71Sopenharmony_ci 114e41f4b71Sopenharmony_ci**Parameters** 115e41f4b71Sopenharmony_ci 116e41f4b71Sopenharmony_ci| Name | Type | Mandatory| Description | 117e41f4b71Sopenharmony_ci| -------- | -------------------------------- | ---- | ------------------------------------ | 118e41f4b71Sopenharmony_ci| value | [BarMode.Fixed](#barmode)| Yes | 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). | 119e41f4b71Sopenharmony_ci 120e41f4b71Sopenharmony_ci### barMode<sup>10+</sup> 121e41f4b71Sopenharmony_ci 122e41f4b71Sopenharmony_cibarMode(value: BarMode.Scrollable, options: ScrollableBarModeOptions) 123e41f4b71Sopenharmony_ci 124e41f4b71Sopenharmony_ciSets the tab bar layout mode to **BarMode.Scrollable**. 125e41f4b71Sopenharmony_ci 126e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 127e41f4b71Sopenharmony_ci 128e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 129e41f4b71Sopenharmony_ci 130e41f4b71Sopenharmony_ci**Parameters** 131e41f4b71Sopenharmony_ci 132e41f4b71Sopenharmony_ci| Name | Type | Mandatory| Description | 133e41f4b71Sopenharmony_ci| -------- | --------------------------------- | ---- | ------------------------------------- | 134e41f4b71Sopenharmony_ci| value | [BarMode.Scrollable](#barmode)| Yes | 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. | 135e41f4b71Sopenharmony_ci| options | [ScrollableBarModeOptions](#scrollablebarmodeoptions10)| Yes | Layout style.| 136e41f4b71Sopenharmony_ci 137e41f4b71Sopenharmony_ci### barWidth 138e41f4b71Sopenharmony_ci 139e41f4b71Sopenharmony_cibarWidth(value: Length) 140e41f4b71Sopenharmony_ci 141e41f4b71Sopenharmony_ciSets the width of the tab bar. A value less than 0 or greater than the width of the **Tabs** component evaluates to the default value. 142e41f4b71Sopenharmony_ci 143e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 144e41f4b71Sopenharmony_ci 145e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 146e41f4b71Sopenharmony_ci 147e41f4b71Sopenharmony_ci**Parameters** 148e41f4b71Sopenharmony_ci 149e41f4b71Sopenharmony_ci| Name| Type | Mandatory| Description | 150e41f4b71Sopenharmony_ci| ------ | ----------------------------------------- | ---- | ------------------------------------------------------------ | 151e41f4b71Sopenharmony_ci| value | [Length](ts-types.md#length)<sup>8+</sup> | Yes | Width of the tab bar.<br>Default value:<br>If neither [SubTabBarStyle](ts-container-tabcontent.md#subtabbarstyle9) nor [BottomTabBarStyle](ts-container-tabcontent.md#bottomtabbarstyle9) is set, and the **vertical** attribute is **false**, the default value is the width of the **Tabs** component.<br>If neither **SubTabBarStyle** nor **BottomTabBarStyle** is set, and the **vertical** attribute is **true**, the default value is 56 vp.<br>If **SubTabBarStyle** is set, and the **vertical** attribute is **false**, the default value is the width of the **Tabs** component.<br>If **SubTabBarStyle** is set, and the **vertical** attribute is **true**, the default value is 56 vp.<br>If **BottomTabBarStyle** is set, and the **vertical** attribute is **true**, the default value is 96 vp.<br>If **BottomTabBarStyle** is set, and the **vertical** attribute is **false**, the default value is the width of the **Tabs** component.| 152e41f4b71Sopenharmony_ci 153e41f4b71Sopenharmony_ci### barHeight 154e41f4b71Sopenharmony_ci 155e41f4b71Sopenharmony_cibarHeight(value: Length) 156e41f4b71Sopenharmony_ci 157e41f4b71Sopenharmony_ciSets the height of the tab bar. A value less than 0 or greater than the height of the **Tabs** component evaluates to the default value. 158e41f4b71Sopenharmony_ci 159e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 160e41f4b71Sopenharmony_ci 161e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 162e41f4b71Sopenharmony_ci 163e41f4b71Sopenharmony_ci**Parameters** 164e41f4b71Sopenharmony_ci 165e41f4b71Sopenharmony_ci| Name| Type | Mandatory| Description | 166e41f4b71Sopenharmony_ci| ------ | ----------------------------------------- | ---- | ------------------------------------------------------------ | 167e41f4b71Sopenharmony_ci| value | [Length](ts-types.md#length)<sup>8+</sup> | Yes | Height of the tab bar.<br>Default value:<br>If the tab bar has the **vertical** attribute set to **false** and does not have a style specified, the default value is 56 vp.<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 [SubTabBarStyle](ts-container-tabcontent.md#subtabbarstyle9) is set, and the **vertical** attribute is **false**, the default value is 56 vp.<br>If **SubTabBarStyle** is set, and the **vertical** attribute is **true**, the default value is the height of the **Tabs** component.<br>If [BottomTabBarStyle](ts-container-tabcontent.md#bottomtabbarstyle9) is set, and the **vertical** attribute is **true**, the default value is the height of the **Tabs** component.<br>If **BottomTabBarStyle** is set, and the **vertical** attribute is **false**, the default value is 56 vp in versions earlier than API version 12 and 52 vp since API version 12.| 168e41f4b71Sopenharmony_ci 169e41f4b71Sopenharmony_ci### animationDuration 170e41f4b71Sopenharmony_ci 171e41f4b71Sopenharmony_cianimationDuration(value: number) 172e41f4b71Sopenharmony_ci 173e41f4b71Sopenharmony_ciSets the length of time required to complete the tab switching animation, which is initiated by clicking a specific tab or by calling the **changeIndex** API of **TabsController**. This parameter cannot be set in percentage. 174e41f4b71Sopenharmony_ci 175e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 176e41f4b71Sopenharmony_ci 177e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 178e41f4b71Sopenharmony_ci 179e41f4b71Sopenharmony_ci**Parameters** 180e41f4b71Sopenharmony_ci 181e41f4b71Sopenharmony_ci| Name| Type | Mandatory| Description | 182e41f4b71Sopenharmony_ci| ------ | ------ | ---- | ------------------------------------------------------------ | 183e41f4b71Sopenharmony_ci| value | number | Yes | Length of time required to complete the tab switching animation, which is initiated by clicking a specific tab or by calling the **changeIndex** API of **TabsController**.<br>The default value varies.<br>API version 10 and earlier versions: If this parameter is set to **null** or is not set, the default value **0** is used, which means that no tab switching animation is displayed when a specific tab is clicked or the **changeIndex** API of **TabsController** is called. If this parameter is set to **undefined** or a value less than 0, the default value **300** is used.<br>API version 11 and later versions: If this parameter is set to an invalid value or is not set, the default value **0** is used when the tab bar is set to **BottomTabBarStyle**; the default value **300** is used when the tab bar is set to any other style.<br>Unit: ms| 184e41f4b71Sopenharmony_ci 185e41f4b71Sopenharmony_ci### animationMode<sup>12+</sup> 186e41f4b71Sopenharmony_ci 187e41f4b71Sopenharmony_cianimationMode(mode: Optional\<AnimationMode\>) 188e41f4b71Sopenharmony_ci 189e41f4b71Sopenharmony_ciSets the animation mode for switching between tabs. 190e41f4b71Sopenharmony_ci 191e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 192e41f4b71Sopenharmony_ci 193e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 194e41f4b71Sopenharmony_ci 195e41f4b71Sopenharmony_ci**Parameters** 196e41f4b71Sopenharmony_ci 197e41f4b71Sopenharmony_ci| Name| Type | Mandatory| Description | 198e41f4b71Sopenharmony_ci| ------ | ------ | ---- | ------------------------------------------------------------ | 199e41f4b71Sopenharmony_ci| mode | Optional\<[AnimationMode](#animationmode12)\>| Yes | Animation mode for switching between tabs.<br>The default value varies.<br>The default value is **AnimationMode.CONTENT_FIRST**, indicating that the content of the target page is loaded before the switching animation starts in the process of switching between tabs.| 200e41f4b71Sopenharmony_ci 201e41f4b71Sopenharmony_ci### barPosition<sup>9+</sup> 202e41f4b71Sopenharmony_ci 203e41f4b71Sopenharmony_cibarPosition(value: BarPosition) 204e41f4b71Sopenharmony_ci 205e41f4b71Sopenharmony_ciPosition of the **Tabs** component. 206e41f4b71Sopenharmony_ci 207e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 208e41f4b71Sopenharmony_ci 209e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 210e41f4b71Sopenharmony_ci 211e41f4b71Sopenharmony_ci**Parameters** 212e41f4b71Sopenharmony_ci 213e41f4b71Sopenharmony_ci| Name| Type | Mandatory| Description | 214e41f4b71Sopenharmony_ci| ----- | ---------------------------------- | ---- | -------------------- | 215e41f4b71Sopenharmony_ci| value | [BarPosition](#barposition)| Yes | Position of the **Tabs** component.<br>Default value: **BarPosition.Start** | 216e41f4b71Sopenharmony_ci 217e41f4b71Sopenharmony_ci### divider<sup>10+</sup> 218e41f4b71Sopenharmony_ci 219e41f4b71Sopenharmony_cidivider(value: DividerStyle | null) 220e41f4b71Sopenharmony_ci 221e41f4b71Sopenharmony_ciSets the divider style for the **TabBar** and **TabContent** components. 222e41f4b71Sopenharmony_ci 223e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 224e41f4b71Sopenharmony_ci 225e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 226e41f4b71Sopenharmony_ci 227e41f4b71Sopenharmony_ci**Parameters** 228e41f4b71Sopenharmony_ci 229e41f4b71Sopenharmony_ci| Name| Type | Mandatory| Description | 230e41f4b71Sopenharmony_ci| ------ | --------------------------------------------------------- | ---- | ------------------------------------------------------------ | 231e41f4b71Sopenharmony_ci| value | [DividerStyle](#dividerstyle10) \| null | Yes | Divider style. By default, the divider is not displayed.<br>**DividerStyle**: divider style.<br>**null**: The divider is not displayed.| 232e41f4b71Sopenharmony_ci 233e41f4b71Sopenharmony_ci### fadingEdge<sup>10+</sup> 234e41f4b71Sopenharmony_ci 235e41f4b71Sopenharmony_cifadingEdge(value: boolean) 236e41f4b71Sopenharmony_ci 237e41f4b71Sopenharmony_ciSets whether the tab fades out when it exceeds the container width. 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. 238e41f4b71Sopenharmony_ci 239e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 240e41f4b71Sopenharmony_ci 241e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 242e41f4b71Sopenharmony_ci 243e41f4b71Sopenharmony_ci**Parameters** 244e41f4b71Sopenharmony_ci 245e41f4b71Sopenharmony_ci| Name| Type | Mandatory| Description | 246e41f4b71Sopenharmony_ci| ------ | ------- | ---- | -------------------------------------------------- | 247e41f4b71Sopenharmony_ci| value | boolean | Yes | Whether the tab fades out when it exceeds the container width.<br>Default value: **true**| 248e41f4b71Sopenharmony_ci 249e41f4b71Sopenharmony_ci### barOverlap<sup>10+</sup> 250e41f4b71Sopenharmony_ci 251e41f4b71Sopenharmony_cibarOverlap(value: boolean) 252e41f4b71Sopenharmony_ci 253e41f4b71Sopenharmony_ciSets whether the tab bar is superimposed on the **TabContent** component after having its background blurred. 254e41f4b71Sopenharmony_ci 255e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 256e41f4b71Sopenharmony_ci 257e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 258e41f4b71Sopenharmony_ci 259e41f4b71Sopenharmony_ci**Parameters** 260e41f4b71Sopenharmony_ci 261e41f4b71Sopenharmony_ci| Name| Type | Mandatory| Description | 262e41f4b71Sopenharmony_ci| ------ | ------- | ---- | ------------------------------------------------------------ | 263e41f4b71Sopenharmony_ci| value | boolean | Yes | Whether the tab bar is superimposed on the **TabContent** component after having its background blurred.<br>Default value: **false**| 264e41f4b71Sopenharmony_ci 265e41f4b71Sopenharmony_ci### barBackgroundColor<sup>10+</sup> 266e41f4b71Sopenharmony_ci 267e41f4b71Sopenharmony_cibarBackgroundColor(value: ResourceColor) 268e41f4b71Sopenharmony_ci 269e41f4b71Sopenharmony_ciBackground color of the tab bar. 270e41f4b71Sopenharmony_ci 271e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 272e41f4b71Sopenharmony_ci 273e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 274e41f4b71Sopenharmony_ci 275e41f4b71Sopenharmony_ci**Parameters** 276e41f4b71Sopenharmony_ci 277e41f4b71Sopenharmony_ci| Name| Type | Mandatory| Description | 278e41f4b71Sopenharmony_ci| ------ | ------------------------------------------ | ---- | ------------------------------------ | 279e41f4b71Sopenharmony_ci| value | [ResourceColor](ts-types.md#resourcecolor) | Yes | Background color of the tab bar.<br>Default value: **Color.Transparent**| 280e41f4b71Sopenharmony_ci 281e41f4b71Sopenharmony_ci### barBackgroundBlurStyle<sup>11+</sup> 282e41f4b71Sopenharmony_ci 283e41f4b71Sopenharmony_cibarBackgroundBlurStyle(value: BlurStyle) 284e41f4b71Sopenharmony_ci 285e41f4b71Sopenharmony_ciSets the background blur style of the tab bar. 286e41f4b71Sopenharmony_ci 287e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 288e41f4b71Sopenharmony_ci 289e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 290e41f4b71Sopenharmony_ci 291e41f4b71Sopenharmony_ci**Parameters** 292e41f4b71Sopenharmony_ci 293e41f4b71Sopenharmony_ci| Name| Type | Mandatory| Description | 294e41f4b71Sopenharmony_ci| ------ | -------------------------------------------- | ---- | ---------------------------------------- | 295e41f4b71Sopenharmony_ci| value | [BlurStyle](ts-universal-attributes-background.md#blurstyle9) | Yes | Background blur style of the tab bar.<br>Default value: **BlurStyle.NONE**| 296e41f4b71Sopenharmony_ci 297e41f4b71Sopenharmony_ci### barGridAlign<sup>10+</sup> 298e41f4b71Sopenharmony_ci 299e41f4b71Sopenharmony_cibarGridAlign(value: BarGridColumnOptions) 300e41f4b71Sopenharmony_ci 301e41f4b71Sopenharmony_ciSets the 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). 302e41f4b71Sopenharmony_ci 303e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 304e41f4b71Sopenharmony_ci 305e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 306e41f4b71Sopenharmony_ci 307e41f4b71Sopenharmony_ci**Parameters** 308e41f4b71Sopenharmony_ci 309e41f4b71Sopenharmony_ci| Name| Type | Mandatory| Description | 310e41f4b71Sopenharmony_ci| ------ | ------------------------------------------------------- | ---- | ---------------------------------- | 311e41f4b71Sopenharmony_ci| value | [BarGridColumnOptions](#bargridcolumnoptions10) | Yes | Visible area of the tab bar in grid mode.| 312e41f4b71Sopenharmony_ci 313e41f4b71Sopenharmony_ci### edgeEffect<sup>12+</sup> 314e41f4b71Sopenharmony_ci 315e41f4b71Sopenharmony_ciedgeEffect(edgeEffect: Optional<EdgeEffect>) 316e41f4b71Sopenharmony_ci 317e41f4b71Sopenharmony_ciSets the edge effect used when the boundary of the scrolling area is reached. 318e41f4b71Sopenharmony_ci 319e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 320e41f4b71Sopenharmony_ci 321e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 322e41f4b71Sopenharmony_ci 323e41f4b71Sopenharmony_ci**Parameters** 324e41f4b71Sopenharmony_ci 325e41f4b71Sopenharmony_ci| Name| Type | Mandatory| Description | 326e41f4b71Sopenharmony_ci| ------ | --------------------------------------------- | ---- | -------------------------------------------- | 327e41f4b71Sopenharmony_ci| edgeEffect | Optional<[EdgeEffect](ts-appendix-enums.md#edgeeffect)> | Yes | Effect used when the boundary of the scrolling area is reached.<br>Default value: **EdgeEffect.Spring**| 328e41f4b71Sopenharmony_ci 329e41f4b71Sopenharmony_ci## DividerStyle<sup>10+</sup> 330e41f4b71Sopenharmony_ci 331e41f4b71Sopenharmony_ciDescribes the divider style. 332e41f4b71Sopenharmony_ci 333e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 334e41f4b71Sopenharmony_ci 335e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 336e41f4b71Sopenharmony_ci 337e41f4b71Sopenharmony_ci| Name | Type | Mandatory | Description | 338e41f4b71Sopenharmony_ci| ----------- | ---------------------------------------- | ---- | ---------------------------------------- | 339e41f4b71Sopenharmony_ci| strokeWidth | [Length](ts-types.md#length) | Yes | Width of the divider. It cannot be set in percentage.<br>Default value: **0.0**<br>Unit: vp | 340e41f4b71Sopenharmony_ci| color | [ResourceColor](ts-types.md#resourcecolor) | No | Color of the divider.<br>Default value: **#33182431** | 341e41f4b71Sopenharmony_ci| 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| 342e41f4b71Sopenharmony_ci| 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| 343e41f4b71Sopenharmony_ci 344e41f4b71Sopenharmony_ci## BarGridColumnOptions<sup>10+</sup> 345e41f4b71Sopenharmony_ci 346e41f4b71Sopenharmony_ciImplements a **BarGridColumnOptions** object for setting the visible area of the tab bar in grid mode, including the column margin and gutter, as well as the number of columns occupied by tabs under small, medium, and large screen sizes. 347e41f4b71Sopenharmony_ci 348e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 349e41f4b71Sopenharmony_ci 350e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 351e41f4b71Sopenharmony_ci 352e41f4b71Sopenharmony_ci| Name | Type | Mandatory | Description | 353e41f4b71Sopenharmony_ci| ----------- | ---------------------------------------- | ---- | ---------------------------------------- | 354e41f4b71Sopenharmony_ci| 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 | 355e41f4b71Sopenharmony_ci| 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 | 356e41f4b71Sopenharmony_ci| 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.| 357e41f4b71Sopenharmony_ci| 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.| 358e41f4b71Sopenharmony_ci| 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.| 359e41f4b71Sopenharmony_ci 360e41f4b71Sopenharmony_ci## ScrollableBarModeOptions<sup>10+</sup> 361e41f4b71Sopenharmony_ci 362e41f4b71Sopenharmony_ciImplements a **ScrollableBarModeOptions** object. 363e41f4b71Sopenharmony_ci 364e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 365e41f4b71Sopenharmony_ci 366e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 367e41f4b71Sopenharmony_ci 368e41f4b71Sopenharmony_ci| Name | Type | Mandatory | Description | 369e41f4b71Sopenharmony_ci| ----------- | ---------------------------------------- | ---- | ---------------------------------------- | 370e41f4b71Sopenharmony_ci| 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 | 371e41f4b71Sopenharmony_ci| nonScrollableLayoutStyle | [LayoutStyle](#layoutstyle10) | No | Tab layout mode of the tab bar when not scrolling in scrollable mode.<br>Default value: **LayoutStyle.ALWAYS_CENTER** | 372e41f4b71Sopenharmony_ci 373e41f4b71Sopenharmony_ci## BarMode 374e41f4b71Sopenharmony_ci 375e41f4b71Sopenharmony_ciEnumerates layout modes of the tab bar. 376e41f4b71Sopenharmony_ci 377e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 378e41f4b71Sopenharmony_ci 379e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 380e41f4b71Sopenharmony_ci 381e41f4b71Sopenharmony_ci| Name | Value| Description | 382e41f4b71Sopenharmony_ci| ---------- | -- | ---------------------------------------- | 383e41f4b71Sopenharmony_ci| Scrollable | 0 | 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.| 384e41f4b71Sopenharmony_ci| Fixed | 1 | 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).| 385e41f4b71Sopenharmony_ci 386e41f4b71Sopenharmony_ci## AnimationMode<sup>12+</sup> 387e41f4b71Sopenharmony_ci 388e41f4b71Sopenharmony_ciEnumerates the animation modes for switching between tabs. 389e41f4b71Sopenharmony_ci 390e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 391e41f4b71Sopenharmony_ci 392e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 393e41f4b71Sopenharmony_ci 394e41f4b71Sopenharmony_ci| Name | Value | Description | 395e41f4b71Sopenharmony_ci| ------------- | -- | ---------------------------------------- | 396e41f4b71Sopenharmony_ci| CONTENT_FIRST | 0 | Load the content of the target page before starting the switching animation.| 397e41f4b71Sopenharmony_ci| ACTION_FIRST | 1 | Start the switching animation before loading the content of the target page. For the settings to take effect, the height and width of tabs must be set to **auto**.| 398e41f4b71Sopenharmony_ci| NO_ANIMATION | 2 | The switching animation is disabled.| 399e41f4b71Sopenharmony_ci 400e41f4b71Sopenharmony_ci## LayoutStyle<sup>10+</sup> 401e41f4b71Sopenharmony_ci 402e41f4b71Sopenharmony_ciEnumerates the tab layout styles of the tab bar when not scrolling in scrollable mode. 403e41f4b71Sopenharmony_ci 404e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 405e41f4b71Sopenharmony_ci 406e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 407e41f4b71Sopenharmony_ci 408e41f4b71Sopenharmony_ci| Name | Value| Description | 409e41f4b71Sopenharmony_ci| ---------- | -- | ---------------------------------------- | 410e41f4b71Sopenharmony_ci| ALWAYS_CENTER | 0 | When the tab content exceeds the tab bar width, the tabs are scrollable.<br>Otherwise, the tabs are compactly centered and not scrollable.| 411e41f4b71Sopenharmony_ci| ALWAYS_AVERAGE_SPLIT | 1 | 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.| 412e41f4b71Sopenharmony_ci| SPACE_BETWEEN_OR_CENTER | 2 | 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.| 413e41f4b71Sopenharmony_ci 414e41f4b71Sopenharmony_ci## Events 415e41f4b71Sopenharmony_ci 416e41f4b71Sopenharmony_ciIn addition to the [universal events](ts-universal-events-click.md), the following events are supported. 417e41f4b71Sopenharmony_ci 418e41f4b71Sopenharmony_ci### onChange 419e41f4b71Sopenharmony_ci 420e41f4b71Sopenharmony_cionChange(event: (index: number) => void) 421e41f4b71Sopenharmony_ci 422e41f4b71Sopenharmony_ciTriggered when a tab is switched. 423e41f4b71Sopenharmony_ci 424e41f4b71Sopenharmony_ciThis event is triggered when any of the following conditions is met: 425e41f4b71Sopenharmony_ci 426e41f4b71Sopenharmony_ci1. The **TabContent** component supports sliding, and the user slides on the tab bar. 427e41f4b71Sopenharmony_ci 428e41f4b71Sopenharmony_ci2. The [Controller](#tabscontroller) API is called. 429e41f4b71Sopenharmony_ci 430e41f4b71Sopenharmony_ci3. The attribute value is updated using a [state variable](../../../quick-start/arkts-state.md). 431e41f4b71Sopenharmony_ci 432e41f4b71Sopenharmony_ci4. A tab is clicked. 433e41f4b71Sopenharmony_ci 434e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 435e41f4b71Sopenharmony_ci 436e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 437e41f4b71Sopenharmony_ci 438e41f4b71Sopenharmony_ci**Parameters** 439e41f4b71Sopenharmony_ci 440e41f4b71Sopenharmony_ci| Name| Type | Mandatory| Description | 441e41f4b71Sopenharmony_ci| ------ | ------ | ---- | -------------------------------------- | 442e41f4b71Sopenharmony_ci| index | number | Yes | Index of the active tab. The index starts from 0.| 443e41f4b71Sopenharmony_ci 444e41f4b71Sopenharmony_ci### onTabBarClick<sup>10+</sup> 445e41f4b71Sopenharmony_ci 446e41f4b71Sopenharmony_cionTabBarClick(event: (index: number) => void) 447e41f4b71Sopenharmony_ci 448e41f4b71Sopenharmony_ciTriggered when a tab is clicked. 449e41f4b71Sopenharmony_ci 450e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 451e41f4b71Sopenharmony_ci 452e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 453e41f4b71Sopenharmony_ci 454e41f4b71Sopenharmony_ci**Parameters** 455e41f4b71Sopenharmony_ci 456e41f4b71Sopenharmony_ci| Name| Type | Mandatory| Description | 457e41f4b71Sopenharmony_ci| ------ | ------ | ---- | ------------------------------------ | 458e41f4b71Sopenharmony_ci| index | number | Yes | Index of the clicked tab. The index starts from 0.| 459e41f4b71Sopenharmony_ci 460e41f4b71Sopenharmony_ci### onAnimationStart<sup>11+</sup> 461e41f4b71Sopenharmony_ci 462e41f4b71Sopenharmony_cionAnimationStart(handler: (index: number, targetIndex: number, event: TabsAnimationEvent) => void) 463e41f4b71Sopenharmony_ci 464e41f4b71Sopenharmony_ciTriggered when the tab switching animation starts. The **index** parameter indicates the index before the animation starts (not the one after). 465e41f4b71Sopenharmony_ci 466e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 467e41f4b71Sopenharmony_ci 468e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 469e41f4b71Sopenharmony_ci 470e41f4b71Sopenharmony_ci**Parameters** 471e41f4b71Sopenharmony_ci 472e41f4b71Sopenharmony_ci| Name | Type | Mandatory| Description | 473e41f4b71Sopenharmony_ci| ----------- | ------------------------------------------------------ | ---- | ------------------------------------------------------------ | 474e41f4b71Sopenharmony_ci| index | number | Yes | Index of the currently displayed element. | 475e41f4b71Sopenharmony_ci| targetIndex | number | Yes | Index of the target element to switch to. | 476e41f4b71Sopenharmony_ci| event | [TabsAnimationEvent](#tabsanimationevent11) | Yes | Extra information of the animation, including the offset of the currently displayed element and target element relative to the start position of the **Tabs** along the main axis, and the hands-off velocity.| 477e41f4b71Sopenharmony_ci 478e41f4b71Sopenharmony_ci### onAnimationEnd<sup>11+</sup> 479e41f4b71Sopenharmony_ci 480e41f4b71Sopenharmony_cionAnimationEnd(handler: (index: number, event: TabsAnimationEvent) => void) 481e41f4b71Sopenharmony_ci 482e41f4b71Sopenharmony_ciTriggered when the tab switching animation ends. This event is triggered when the tab switching animation ends, whether it is caused by gesture interruption or not. The **index** parameter indicates the index after the animation ends. 483e41f4b71Sopenharmony_ci 484e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 485e41f4b71Sopenharmony_ci 486e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 487e41f4b71Sopenharmony_ci 488e41f4b71Sopenharmony_ci**Parameters** 489e41f4b71Sopenharmony_ci 490e41f4b71Sopenharmony_ci| Name| Type | Mandatory| Description | 491e41f4b71Sopenharmony_ci| ------ | ------------------------------------------------------ | ---- | ------------------------------------------------------------ | 492e41f4b71Sopenharmony_ci| index | number | Yes | Index of the currently displayed element. | 493e41f4b71Sopenharmony_ci| event | [TabsAnimationEvent](#tabsanimationevent11) | Yes | Extra information of the animation, which is the offset of the currently displayed element relative to the start position of the **Tabs** along the main axis.| 494e41f4b71Sopenharmony_ci 495e41f4b71Sopenharmony_ci### onGestureSwipe<sup>11+</sup> 496e41f4b71Sopenharmony_ci 497e41f4b71Sopenharmony_cionGestureSwipe(handler: (index: number, event: TabsAnimationEvent) => void) 498e41f4b71Sopenharmony_ci 499e41f4b71Sopenharmony_ciTriggered on a frame-by-frame basis when the tab is switched by a swipe. 500e41f4b71Sopenharmony_ci 501e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 502e41f4b71Sopenharmony_ci 503e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 504e41f4b71Sopenharmony_ci 505e41f4b71Sopenharmony_ci**Parameters** 506e41f4b71Sopenharmony_ci 507e41f4b71Sopenharmony_ci| Name| Type | Mandatory| Description | 508e41f4b71Sopenharmony_ci| ------ | ------------------------------------------------------ | ---- | ------------------------------------------------------------ | 509e41f4b71Sopenharmony_ci| index | number | Yes | Index of the currently displayed element. | 510e41f4b71Sopenharmony_ci| event | [TabsAnimationEvent](#tabsanimationevent11) | Yes | Extra information of the animation, which is the offset of the currently displayed element relative to the start position of the **Tabs** along the main axis.| 511e41f4b71Sopenharmony_ci 512e41f4b71Sopenharmony_ci### customContentTransition<sup>11+</sup> 513e41f4b71Sopenharmony_ci 514e41f4b71Sopenharmony_cicustomContentTransition(delegate: (from: number, to: number) => TabContentAnimatedTransition \| undefined) 515e41f4b71Sopenharmony_ci 516e41f4b71Sopenharmony_ciSets the custom tab switching animation. 517e41f4b71Sopenharmony_ci 518e41f4b71Sopenharmony_ciInstructions: 519e41f4b71Sopenharmony_ci 520e41f4b71Sopenharmony_ci1. When the custom tab switching animation is used, the default switching animation of the **Tabs** component is disabled, and tabs cannot be switched through swiping.<br>2. The value **undefined** means not to use the custom tab switching animation, in which case the default switching animation is used.<br>3. The custom tab switching animation cannot be interrupted.<br>4. Currently, the custom tab switching animation can be triggered only by clicking a tab or by calling the **TabsController.changeIndex()** API.<br>5. When the custom tab switching animation is used, the **Tabs** component supports all events except **onGestureSwipe**.<br>6. Notes about the **onChange** and **onAnimationEnd** events: If the second custom animation is triggered during the execution of the first custom animation, the **onChange** and **onAnimationEnd** events of the first custom animation will be triggered when the second custom animation starts.<br>7. When the custom animation is used, the stack layout is used for pages involved in the animation. If the **zIndex** attribute is not set for related pages, the **zIndex** values of all pages are the same. In this case, the pages are rendered in the order in which they are added to the component tree (that is, the sequence of page indexes). In light of this, to control the rendering levels of pages, set the **zIndex** attribute of the pages. 521e41f4b71Sopenharmony_ci 522e41f4b71Sopenharmony_ci**Widget capability**: This API can be used in ArkTS widgets since API version 11. 523e41f4b71Sopenharmony_ci 524e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 525e41f4b71Sopenharmony_ci 526e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 527e41f4b71Sopenharmony_ci 528e41f4b71Sopenharmony_ci**Parameters** 529e41f4b71Sopenharmony_ci 530e41f4b71Sopenharmony_ci| Name| Type | Mandatory| Description | 531e41f4b71Sopenharmony_ci| ------ | ------ | ---- | ------------------------------- | 532e41f4b71Sopenharmony_ci| from | number | Yes | Index of the currently displayed tab before the animation starts.| 533e41f4b71Sopenharmony_ci| to | number | Yes | Index of the target tab before the animation starts.| 534e41f4b71Sopenharmony_ci 535e41f4b71Sopenharmony_ci**Return value** 536e41f4b71Sopenharmony_ci 537e41f4b71Sopenharmony_ci| Type | Description | 538e41f4b71Sopenharmony_ci| ------------------------------------------------------------ | ------------------------ | 539e41f4b71Sopenharmony_ci| [TabContentAnimatedTransition](#tabcontentanimatedtransition11) \| undefined | Information about the custom tab switching animation.| 540e41f4b71Sopenharmony_ci 541e41f4b71Sopenharmony_ci### onContentWillChange<sup>12+</sup> 542e41f4b71Sopenharmony_ci 543e41f4b71Sopenharmony_cionContentWillChange(handler: (currentIndex: number, comingIndex: number) => boolean) 544e41f4b71Sopenharmony_ci 545e41f4b71Sopenharmony_ciTriggered when a new page is about to be displayed. 546e41f4b71Sopenharmony_ci 547e41f4b71Sopenharmony_ciSpecifically, this event is triggered in the following cases: 548e41f4b71Sopenharmony_ci 549e41f4b71Sopenharmony_ci1. When the user swipes on the **TabContent** component (provided that it supports swiping) to switch to a new page. 550e41f4b71Sopenharmony_ci 551e41f4b71Sopenharmony_ci2. When **TabsController.changeIndex** is called to switch to a new page. 552e41f4b71Sopenharmony_ci 553e41f4b71Sopenharmony_ci3. When the **index** attribute is changed to switch to a new page. 554e41f4b71Sopenharmony_ci 555e41f4b71Sopenharmony_ci4. When the user clicks a tab on the tab bar to switch to a new page. 556e41f4b71Sopenharmony_ci 557e41f4b71Sopenharmony_ci5. When the user presses the left or right arrow key on the keyboard to switch to a new page while the tab bar is focused. 558e41f4b71Sopenharmony_ci 559e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 560e41f4b71Sopenharmony_ci 561e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 562e41f4b71Sopenharmony_ci 563e41f4b71Sopenharmony_ci**Parameters** 564e41f4b71Sopenharmony_ci 565e41f4b71Sopenharmony_ci| Name | Type | Mandatory| Description | 566e41f4b71Sopenharmony_ci| ------------ | ------ | ---- | ------------------------------------------ | 567e41f4b71Sopenharmony_ci| currentIndex | number | Yes | Index of the active tab. The index starts from 0.| 568e41f4b71Sopenharmony_ci| comingIndex | number | Yes | Index of the new tab to be displayed. | 569e41f4b71Sopenharmony_ci 570e41f4b71Sopenharmony_ci**Return value** 571e41f4b71Sopenharmony_ci 572e41f4b71Sopenharmony_ci| Type | Description | 573e41f4b71Sopenharmony_ci| ------- | ------------------------------------------------------------ | 574e41f4b71Sopenharmony_ci| boolean | The value **true** means that the tab can switch to the new page.<br>The value **false** means that the tab cannot switch to the new page and will remain on the current page.| 575e41f4b71Sopenharmony_ci 576e41f4b71Sopenharmony_ci## TabsAnimationEvent<sup>11+</sup> 577e41f4b71Sopenharmony_ci 578e41f4b71Sopenharmony_ciDescribes the animation information of the **Tabs** component. 579e41f4b71Sopenharmony_ci 580e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 581e41f4b71Sopenharmony_ci 582e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 583e41f4b71Sopenharmony_ci 584e41f4b71Sopenharmony_ci| Name | Type | Read Only| Optional| Description | 585e41f4b71Sopenharmony_ci| ------------- | ---------- | ---- | ---- | ------------------------ | 586e41f4b71Sopenharmony_ci| currentOffset | number | No| No| Offset of the currently displayed element relative to the start position of the **Tabs** component along the main axis.<br> Unit: vp<br>Default value: **0**| 587e41f4b71Sopenharmony_ci| targetOffset | number | No| No| Offset of the target element relative to the start position of the **Tabs** component along the main axis.<br> Unit: vp<br>Default value: **0**| 588e41f4b71Sopenharmony_ci| velocity | number | No| No| Hands-off velocity at the beginning of the animation. Unit: VP/S<br>Default value: **0**| 589e41f4b71Sopenharmony_ci 590e41f4b71Sopenharmony_ci## TabContentAnimatedTransition<sup>11+</sup> 591e41f4b71Sopenharmony_ci 592e41f4b71Sopenharmony_ciProvides the information about the custom tab page switching animation. 593e41f4b71Sopenharmony_ci 594e41f4b71Sopenharmony_ci**Widget capability**: This API can be used in ArkTS widgets since API version 11. 595e41f4b71Sopenharmony_ci 596e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 597e41f4b71Sopenharmony_ci 598e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 599e41f4b71Sopenharmony_ci 600e41f4b71Sopenharmony_ci| Name | Type | Mandatory | Description | 601e41f4b71Sopenharmony_ci| ------------- | ---------------------- | ---- |---------------------- | 602e41f4b71Sopenharmony_ci| timeout | number | No| Timeout for the custom switching animation. The timer starts when the switching begins. If this timeframe passes without you calling the **finishTransition** API in [TabContentTransitionProxy](#tabcontenttransitionproxy11), the component will assume that the custom animation has ended and will proceed directly with subsequent operations. Unit: ms<br>Default value: **1000**| 603e41f4b71Sopenharmony_ci| transition | (proxy: [TabContentTransitionProxy](#tabcontenttransitionproxy11)) => void | Yes| Content of the custom switching animation.| 604e41f4b71Sopenharmony_ci 605e41f4b71Sopenharmony_ci## TabContentTransitionProxy<sup>11+</sup> 606e41f4b71Sopenharmony_ci 607e41f4b71Sopenharmony_ciImplements the proxy object returned during the execution of the custom switching animation of the **Tabs** component. You can use this object to obtain the start and target pages for the custom tab switching animation. In addition, you can call the **finishTransition** API of this object to notify the **Tabs** component of the ending of the custom animation. 608e41f4b71Sopenharmony_ci 609e41f4b71Sopenharmony_ci**Widget capability**: This API can be used in ArkTS widgets since API version 11. 610e41f4b71Sopenharmony_ci 611e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 612e41f4b71Sopenharmony_ci 613e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 614e41f4b71Sopenharmony_ci 615e41f4b71Sopenharmony_ci### Attributes 616e41f4b71Sopenharmony_ci 617e41f4b71Sopenharmony_ci| Name | Type | Read Only| Optional| Description | 618e41f4b71Sopenharmony_ci| ----- | ------- | ---- | ---- | --------------------------- | 619e41f4b71Sopenharmony_ci| from | number | No| No| Index of the starting page of the custom animation.| 620e41f4b71Sopenharmony_ci| to | number | No| No| Index of the target tab to switch to.| 621e41f4b71Sopenharmony_ci 622e41f4b71Sopenharmony_ci### finishTransition 623e41f4b71Sopenharmony_ci 624e41f4b71Sopenharmony_cifinishTransition(): void 625e41f4b71Sopenharmony_ci 626e41f4b71Sopenharmony_ciNotifies the **Tabs** component that the custom animation has finished playing. 627e41f4b71Sopenharmony_ci 628e41f4b71Sopenharmony_ci**Widget capability**: This API can be used in ArkTS widgets since API version 11. 629e41f4b71Sopenharmony_ci 630e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 631e41f4b71Sopenharmony_ci 632e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 633e41f4b71Sopenharmony_ci 634e41f4b71Sopenharmony_ci## TabsController 635e41f4b71Sopenharmony_ci 636e41f4b71Sopenharmony_ciDefines a tab controller, which is used to control switching of tabs. One **TabsController** cannot control multiple **Tabs** components. 637e41f4b71Sopenharmony_ci 638e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 639e41f4b71Sopenharmony_ci 640e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 641e41f4b71Sopenharmony_ci 642e41f4b71Sopenharmony_ci### Objects to Import 643e41f4b71Sopenharmony_ci 644e41f4b71Sopenharmony_ci```ts 645e41f4b71Sopenharmony_cilet controller: TabsController = new TabsController() 646e41f4b71Sopenharmony_ci``` 647e41f4b71Sopenharmony_ci 648e41f4b71Sopenharmony_ci### constructor 649e41f4b71Sopenharmony_ci 650e41f4b71Sopenharmony_ciconstructor() 651e41f4b71Sopenharmony_ci 652e41f4b71Sopenharmony_ciA constructor used to create a **TabsController** object. 653e41f4b71Sopenharmony_ci 654e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 655e41f4b71Sopenharmony_ci 656e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 657e41f4b71Sopenharmony_ci 658e41f4b71Sopenharmony_ci### changeIndex 659e41f4b71Sopenharmony_ci 660e41f4b71Sopenharmony_cichangeIndex(value: number): void 661e41f4b71Sopenharmony_ci 662e41f4b71Sopenharmony_ciSwitches to the specified tab. 663e41f4b71Sopenharmony_ci 664e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11. 665e41f4b71Sopenharmony_ci 666e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 667e41f4b71Sopenharmony_ci 668e41f4b71Sopenharmony_ci**Parameters** 669e41f4b71Sopenharmony_ci 670e41f4b71Sopenharmony_ci| Name | Type | Mandatory | Description | 671e41f4b71Sopenharmony_ci| ----- | ------ | ---- | ---------------------------------------- | 672e41f4b71Sopenharmony_ci| 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.| 673e41f4b71Sopenharmony_ci 674e41f4b71Sopenharmony_ci### preloadItems<sup>12+</sup> 675e41f4b71Sopenharmony_ci 676e41f4b71Sopenharmony_cipreloadItems(indices: Optional\<Array\<number>>): Promise\<void> 677e41f4b71Sopenharmony_ci 678e41f4b71Sopenharmony_ciPreloads child nodes. After this API is called, all specified child nodes will be loaded at once. Therefore, for performance considerations, it is recommended that you load child nodes in batches. 679e41f4b71Sopenharmony_ci 680e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 681e41f4b71Sopenharmony_ci 682e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 683e41f4b71Sopenharmony_ci 684e41f4b71Sopenharmony_ci**Parameters** 685e41f4b71Sopenharmony_ci 686e41f4b71Sopenharmony_ci| Name | Type | Mandatory | Description | 687e41f4b71Sopenharmony_ci| ----- | ------ | ---- | ---------------------------------------- | 688e41f4b71Sopenharmony_ci| indices | Optional\<Array\<number>> | Yes| Array of indexes of the child nodes to preload.<br>The default value is an empty array.| 689e41f4b71Sopenharmony_ci 690e41f4b71Sopenharmony_ci**Return value** 691e41f4b71Sopenharmony_ci 692e41f4b71Sopenharmony_ci| Type | Description | 693e41f4b71Sopenharmony_ci| ------------------------------------------------------------ | ------------------------ | 694e41f4b71Sopenharmony_ci| Promise\<void> | Promise used to return the value.| 695e41f4b71Sopenharmony_ci 696e41f4b71Sopenharmony_ci**Error codes** 697e41f4b71Sopenharmony_ci 698e41f4b71Sopenharmony_ciFor details about the error codes, see [Universal Error Codes](../../errorcode-universal.md). 699e41f4b71Sopenharmony_ci 700e41f4b71Sopenharmony_ci| ID | Error Message | 701e41f4b71Sopenharmony_ci| -------- | -------------------------------------------- | 702e41f4b71Sopenharmony_ci| 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. | 703e41f4b71Sopenharmony_ci 704e41f4b71Sopenharmony_ci## Example 705e41f4b71Sopenharmony_ci 706e41f4b71Sopenharmony_ci### Example 1 707e41f4b71Sopenharmony_ci 708e41f4b71Sopenharmony_ciThis example uses **onChange** to implement the linkage between **tabBar** and **TabContent**. 709e41f4b71Sopenharmony_ci 710e41f4b71Sopenharmony_ci```ts 711e41f4b71Sopenharmony_ci// xxx.ets 712e41f4b71Sopenharmony_ci@Entry 713e41f4b71Sopenharmony_ci@Component 714e41f4b71Sopenharmony_cistruct TabsExample { 715e41f4b71Sopenharmony_ci @State fontColor: string = '#182431' 716e41f4b71Sopenharmony_ci @State selectedFontColor: string = '#007DFF' 717e41f4b71Sopenharmony_ci @State currentIndex: number = 0 718e41f4b71Sopenharmony_ci private controller: TabsController = new TabsController() 719e41f4b71Sopenharmony_ci 720e41f4b71Sopenharmony_ci @Builder tabBuilder(index: number, name: string) { 721e41f4b71Sopenharmony_ci Column() { 722e41f4b71Sopenharmony_ci Text(name) 723e41f4b71Sopenharmony_ci .fontColor(this.currentIndex === index ? this.selectedFontColor : this.fontColor) 724e41f4b71Sopenharmony_ci .fontSize(16) 725e41f4b71Sopenharmony_ci .fontWeight(this.currentIndex === index ? 500 : 400) 726e41f4b71Sopenharmony_ci .lineHeight(22) 727e41f4b71Sopenharmony_ci .margin({ top: 17, bottom: 7 }) 728e41f4b71Sopenharmony_ci Divider() 729e41f4b71Sopenharmony_ci .strokeWidth(2) 730e41f4b71Sopenharmony_ci .color('#007DFF') 731e41f4b71Sopenharmony_ci .opacity(this.currentIndex === index ? 1 : 0) 732e41f4b71Sopenharmony_ci }.width('100%') 733e41f4b71Sopenharmony_ci } 734e41f4b71Sopenharmony_ci 735e41f4b71Sopenharmony_ci build() { 736e41f4b71Sopenharmony_ci Column() { 737e41f4b71Sopenharmony_ci Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) { 738e41f4b71Sopenharmony_ci TabContent() { 739e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor('#00CB87') 740e41f4b71Sopenharmony_ci }.tabBar(this.tabBuilder(0, 'green')) 741e41f4b71Sopenharmony_ci 742e41f4b71Sopenharmony_ci TabContent() { 743e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor('#007DFF') 744e41f4b71Sopenharmony_ci }.tabBar(this.tabBuilder(1, 'blue')) 745e41f4b71Sopenharmony_ci 746e41f4b71Sopenharmony_ci TabContent() { 747e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor('#FFBF00') 748e41f4b71Sopenharmony_ci }.tabBar(this.tabBuilder(2, 'yellow')) 749e41f4b71Sopenharmony_ci 750e41f4b71Sopenharmony_ci TabContent() { 751e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor('#E67C92') 752e41f4b71Sopenharmony_ci }.tabBar(this.tabBuilder(3, 'pink')) 753e41f4b71Sopenharmony_ci } 754e41f4b71Sopenharmony_ci .vertical(false) 755e41f4b71Sopenharmony_ci .barMode(BarMode.Fixed) 756e41f4b71Sopenharmony_ci .barWidth(360) 757e41f4b71Sopenharmony_ci .barHeight(56) 758e41f4b71Sopenharmony_ci .animationDuration(400) 759e41f4b71Sopenharmony_ci .onChange((index: number) => { 760e41f4b71Sopenharmony_ci this.currentIndex = index 761e41f4b71Sopenharmony_ci }) 762e41f4b71Sopenharmony_ci .width(360) 763e41f4b71Sopenharmony_ci .height(296) 764e41f4b71Sopenharmony_ci .margin({ top: 52 }) 765e41f4b71Sopenharmony_ci .backgroundColor('#F1F3F5') 766e41f4b71Sopenharmony_ci }.width('100%') 767e41f4b71Sopenharmony_ci } 768e41f4b71Sopenharmony_ci} 769e41f4b71Sopenharmony_ci``` 770e41f4b71Sopenharmony_ci 771e41f4b71Sopenharmony_ci 772e41f4b71Sopenharmony_ci 773e41f4b71Sopenharmony_ci### Example 2 774e41f4b71Sopenharmony_ci 775e41f4b71Sopenharmony_ciThis example uses **divider** to present dividers in different styles. 776e41f4b71Sopenharmony_ci 777e41f4b71Sopenharmony_ci```ts 778e41f4b71Sopenharmony_ci// xxx.ets 779e41f4b71Sopenharmony_ci@Entry 780e41f4b71Sopenharmony_ci@Component 781e41f4b71Sopenharmony_cistruct TabsDivider1 { 782e41f4b71Sopenharmony_ci private controller1: TabsController = new TabsController() 783e41f4b71Sopenharmony_ci @State dividerColor: string = 'red' 784e41f4b71Sopenharmony_ci @State strokeWidth: number = 2 785e41f4b71Sopenharmony_ci @State startMargin: number = 0 786e41f4b71Sopenharmony_ci @State endMargin: number = 0 787e41f4b71Sopenharmony_ci @State nullFlag: boolean = false 788e41f4b71Sopenharmony_ci 789e41f4b71Sopenharmony_ci build() { 790e41f4b71Sopenharmony_ci Column() { 791e41f4b71Sopenharmony_ci Tabs({ controller: this.controller1 }) { 792e41f4b71Sopenharmony_ci TabContent() { 793e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Pink) 794e41f4b71Sopenharmony_ci }.tabBar('pink') 795e41f4b71Sopenharmony_ci 796e41f4b71Sopenharmony_ci TabContent() { 797e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Yellow) 798e41f4b71Sopenharmony_ci }.tabBar('yellow') 799e41f4b71Sopenharmony_ci 800e41f4b71Sopenharmony_ci TabContent() { 801e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Blue) 802e41f4b71Sopenharmony_ci }.tabBar('blue') 803e41f4b71Sopenharmony_ci 804e41f4b71Sopenharmony_ci TabContent() { 805e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Green) 806e41f4b71Sopenharmony_ci }.tabBar('green') 807e41f4b71Sopenharmony_ci 808e41f4b71Sopenharmony_ci TabContent() { 809e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Red) 810e41f4b71Sopenharmony_ci }.tabBar('red') 811e41f4b71Sopenharmony_ci } 812e41f4b71Sopenharmony_ci .vertical(true) 813e41f4b71Sopenharmony_ci .scrollable(true) 814e41f4b71Sopenharmony_ci .barMode(BarMode.Fixed) 815e41f4b71Sopenharmony_ci .barWidth(70) 816e41f4b71Sopenharmony_ci .barHeight(200) 817e41f4b71Sopenharmony_ci .animationDuration(400) 818e41f4b71Sopenharmony_ci .onChange((index: number) => { 819e41f4b71Sopenharmony_ci console.info(index.toString()) 820e41f4b71Sopenharmony_ci }) 821e41f4b71Sopenharmony_ci .height('200vp') 822e41f4b71Sopenharmony_ci .margin({ bottom: '12vp' }) 823e41f4b71Sopenharmony_ci .divider(this.nullFlag ? null : { 824e41f4b71Sopenharmony_ci strokeWidth: this.strokeWidth, 825e41f4b71Sopenharmony_ci color: this.dividerColor, 826e41f4b71Sopenharmony_ci startMargin: this.startMargin, 827e41f4b71Sopenharmony_ci endMargin: this.endMargin 828e41f4b71Sopenharmony_ci }) 829e41f4b71Sopenharmony_ci 830e41f4b71Sopenharmony_ci Button ('Regular Divider').width('100%').margin({ bottom: '12vp'}) 831e41f4b71Sopenharmony_ci .onClick(() => { 832e41f4b71Sopenharmony_ci this.nullFlag = false; 833e41f4b71Sopenharmony_ci this.strokeWidth = 2; 834e41f4b71Sopenharmony_ci this.dividerColor = 'red'; 835e41f4b71Sopenharmony_ci this.startMargin = 0; 836e41f4b71Sopenharmony_ci this.endMargin = 0; 837e41f4b71Sopenharmony_ci }) 838e41f4b71Sopenharmony_ci Button('Empty Divider').width('100%').margin({ bottom: '12vp' }) 839e41f4b71Sopenharmony_ci .onClick(() => { 840e41f4b71Sopenharmony_ci this.nullFlag = true 841e41f4b71Sopenharmony_ci }) 842e41f4b71Sopenharmony_ci Button('Change to Blue').width('100%').margin({ bottom: '12vp'}) 843e41f4b71Sopenharmony_ci .onClick(() => { 844e41f4b71Sopenharmony_ci this.dividerColor = 'blue' 845e41f4b71Sopenharmony_ci }) 846e41f4b71Sopenharmony_ci Button('Increase Width').width('100%').margin({ bottom: '12vp' }) 847e41f4b71Sopenharmony_ci .onClick(() => { 848e41f4b71Sopenharmony_ci this.strokeWidth += 2 849e41f4b71Sopenharmony_ci }) 850e41f4b71Sopenharmony_ci Button('Decrease Width').width('100%').margin({ bottom: '12vp'}) 851e41f4b71Sopenharmony_ci .onClick(() => { 852e41f4b71Sopenharmony_ci if (this.strokeWidth > 2) { 853e41f4b71Sopenharmony_ci this.strokeWidth -= 2 854e41f4b71Sopenharmony_ci } 855e41f4b71Sopenharmony_ci }) 856e41f4b71Sopenharmony_ci Button ('Increase Top Margin').width ('100%').margin ({ bottom:'12vp'}) 857e41f4b71Sopenharmony_ci .onClick(() => { 858e41f4b71Sopenharmony_ci this.startMargin += 2 859e41f4b71Sopenharmony_ci }) 860e41f4b71Sopenharmony_ci Button ('Decrease Top Margin').width ('100%').margin ({ bottom:'12vp' }) 861e41f4b71Sopenharmony_ci .onClick(() => { 862e41f4b71Sopenharmony_ci if (this.startMargin > 2) { 863e41f4b71Sopenharmony_ci this.startMargin -= 2 864e41f4b71Sopenharmony_ci } 865e41f4b71Sopenharmony_ci }) 866e41f4b71Sopenharmony_ci Button ('Increase Bottom Margin').width ('100%').margin ({ bottom:'12vp'}) 867e41f4b71Sopenharmony_ci .onClick(() => { 868e41f4b71Sopenharmony_ci this.endMargin += 2 869e41f4b71Sopenharmony_ci }) 870e41f4b71Sopenharmony_ci Button ('Decrease Bottom Margin').width ('100%').margin ({ bottom:'12vp' }) 871e41f4b71Sopenharmony_ci .onClick(() => { 872e41f4b71Sopenharmony_ci if (this.endMargin > 2) { 873e41f4b71Sopenharmony_ci this.endMargin -= 2 874e41f4b71Sopenharmony_ci } 875e41f4b71Sopenharmony_ci }) 876e41f4b71Sopenharmony_ci }.padding({ top: '24vp', left: '24vp', right: '24vp' }) 877e41f4b71Sopenharmony_ci } 878e41f4b71Sopenharmony_ci} 879e41f4b71Sopenharmony_ci``` 880e41f4b71Sopenharmony_ci 881e41f4b71Sopenharmony_ci 882e41f4b71Sopenharmony_ci 883e41f4b71Sopenharmony_ci### Example 3 884e41f4b71Sopenharmony_ci 885e41f4b71Sopenharmony_ciThis example uses **fadingEdge** to specify whether to fade out tabs. 886e41f4b71Sopenharmony_ci 887e41f4b71Sopenharmony_ci```ts 888e41f4b71Sopenharmony_ci// xxx.ets 889e41f4b71Sopenharmony_ci@Entry 890e41f4b71Sopenharmony_ci@Component 891e41f4b71Sopenharmony_cistruct TabsOpaque { 892e41f4b71Sopenharmony_ci @State message: string = 'Hello World' 893e41f4b71Sopenharmony_ci private controller: TabsController = new TabsController() 894e41f4b71Sopenharmony_ci private controller1: TabsController = new TabsController() 895e41f4b71Sopenharmony_ci @State selfFadingFade: boolean = true; 896e41f4b71Sopenharmony_ci 897e41f4b71Sopenharmony_ci build() { 898e41f4b71Sopenharmony_ci Column() { 899e41f4b71Sopenharmony_ci Button (Set Tab to Fade').width ('100%').margin ({bottom: '12vp'}) 900e41f4b71Sopenharmony_ci .onClick((event?: ClickEvent) => { 901e41f4b71Sopenharmony_ci this.selfFadingFade = true; 902e41f4b71Sopenharmony_ci }) 903e41f4b71Sopenharmony_ci Button (Set Tab Not to Fade').width ('100%').margin ({bottom: '12vp'}) 904e41f4b71Sopenharmony_ci .onClick((event?: ClickEvent) => { 905e41f4b71Sopenharmony_ci this.selfFadingFade = false; 906e41f4b71Sopenharmony_ci }) 907e41f4b71Sopenharmony_ci Tabs({ barPosition: BarPosition.End, controller: this.controller }) { 908e41f4b71Sopenharmony_ci TabContent() { 909e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Pink) 910e41f4b71Sopenharmony_ci }.tabBar('pink') 911e41f4b71Sopenharmony_ci 912e41f4b71Sopenharmony_ci TabContent() { 913e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Yellow) 914e41f4b71Sopenharmony_ci }.tabBar('yellow') 915e41f4b71Sopenharmony_ci 916e41f4b71Sopenharmony_ci TabContent() { 917e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Blue) 918e41f4b71Sopenharmony_ci }.tabBar('blue') 919e41f4b71Sopenharmony_ci 920e41f4b71Sopenharmony_ci TabContent() { 921e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Green) 922e41f4b71Sopenharmony_ci }.tabBar('green') 923e41f4b71Sopenharmony_ci 924e41f4b71Sopenharmony_ci TabContent() { 925e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Green) 926e41f4b71Sopenharmony_ci }.tabBar('green') 927e41f4b71Sopenharmony_ci 928e41f4b71Sopenharmony_ci TabContent() { 929e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Green) 930e41f4b71Sopenharmony_ci }.tabBar('green') 931e41f4b71Sopenharmony_ci 932e41f4b71Sopenharmony_ci TabContent() { 933e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Green) 934e41f4b71Sopenharmony_ci }.tabBar('green') 935e41f4b71Sopenharmony_ci 936e41f4b71Sopenharmony_ci TabContent() { 937e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Green) 938e41f4b71Sopenharmony_ci }.tabBar('green') 939e41f4b71Sopenharmony_ci } 940e41f4b71Sopenharmony_ci .vertical(false) 941e41f4b71Sopenharmony_ci .scrollable(true) 942e41f4b71Sopenharmony_ci .barMode(BarMode.Scrollable) 943e41f4b71Sopenharmony_ci .barHeight(80) 944e41f4b71Sopenharmony_ci .animationDuration(400) 945e41f4b71Sopenharmony_ci .onChange((index: number) => { 946e41f4b71Sopenharmony_ci console.info(index.toString()) 947e41f4b71Sopenharmony_ci }) 948e41f4b71Sopenharmony_ci .fadingEdge(this.selfFadingFade) 949e41f4b71Sopenharmony_ci .height('30%') 950e41f4b71Sopenharmony_ci .width('100%') 951e41f4b71Sopenharmony_ci 952e41f4b71Sopenharmony_ci Tabs({ barPosition: BarPosition.Start, controller: this.controller1 }) { 953e41f4b71Sopenharmony_ci TabContent() { 954e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Pink) 955e41f4b71Sopenharmony_ci }.tabBar('pink') 956e41f4b71Sopenharmony_ci 957e41f4b71Sopenharmony_ci TabContent() { 958e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Yellow) 959e41f4b71Sopenharmony_ci }.tabBar('yellow') 960e41f4b71Sopenharmony_ci 961e41f4b71Sopenharmony_ci TabContent() { 962e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Blue) 963e41f4b71Sopenharmony_ci }.tabBar('blue') 964e41f4b71Sopenharmony_ci 965e41f4b71Sopenharmony_ci TabContent() { 966e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Green) 967e41f4b71Sopenharmony_ci }.tabBar('green') 968e41f4b71Sopenharmony_ci 969e41f4b71Sopenharmony_ci TabContent() { 970e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Green) 971e41f4b71Sopenharmony_ci }.tabBar('green') 972e41f4b71Sopenharmony_ci 973e41f4b71Sopenharmony_ci TabContent() { 974e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Green) 975e41f4b71Sopenharmony_ci }.tabBar('green') 976e41f4b71Sopenharmony_ci } 977e41f4b71Sopenharmony_ci .vertical(true) 978e41f4b71Sopenharmony_ci .scrollable(true) 979e41f4b71Sopenharmony_ci .barMode(BarMode.Scrollable) 980e41f4b71Sopenharmony_ci .barHeight(200) 981e41f4b71Sopenharmony_ci .barWidth(80) 982e41f4b71Sopenharmony_ci .animationDuration(400) 983e41f4b71Sopenharmony_ci .onChange((index: number) => { 984e41f4b71Sopenharmony_ci console.info(index.toString()) 985e41f4b71Sopenharmony_ci }) 986e41f4b71Sopenharmony_ci .fadingEdge(this.selfFadingFade) 987e41f4b71Sopenharmony_ci .height('30%') 988e41f4b71Sopenharmony_ci .width('100%') 989e41f4b71Sopenharmony_ci } 990e41f4b71Sopenharmony_ci .padding({ top: '24vp', left: '24vp', right: '24vp' }) 991e41f4b71Sopenharmony_ci } 992e41f4b71Sopenharmony_ci} 993e41f4b71Sopenharmony_ci``` 994e41f4b71Sopenharmony_ci 995e41f4b71Sopenharmony_ci 996e41f4b71Sopenharmony_ci 997e41f4b71Sopenharmony_ci### Example 4 998e41f4b71Sopenharmony_ci 999e41f4b71Sopenharmony_ciThis example uses **barOverlap** to specify whether the tab bar is superimposed on the **TabContent** component after having its background blurred. 1000e41f4b71Sopenharmony_ci 1001e41f4b71Sopenharmony_ci```ts 1002e41f4b71Sopenharmony_ci// xxx.ets 1003e41f4b71Sopenharmony_ci@Entry 1004e41f4b71Sopenharmony_ci@Component 1005e41f4b71Sopenharmony_cistruct barBackgroundColorTest { 1006e41f4b71Sopenharmony_ci private controller: TabsController = new TabsController() 1007e41f4b71Sopenharmony_ci @State barOverlap: boolean = true; 1008e41f4b71Sopenharmony_ci @State barBackgroundColor: string = '#88888888'; 1009e41f4b71Sopenharmony_ci 1010e41f4b71Sopenharmony_ci build() { 1011e41f4b71Sopenharmony_ci Column() { 1012e41f4b71Sopenharmony_ci Button ("Change barOverlap").width ('100%').margin ({ bottom:'12vp'}) 1013e41f4b71Sopenharmony_ci .onClick((event?: ClickEvent) => { 1014e41f4b71Sopenharmony_ci if (this.barOverlap) { 1015e41f4b71Sopenharmony_ci this.barOverlap = false; 1016e41f4b71Sopenharmony_ci } else { 1017e41f4b71Sopenharmony_ci this.barOverlap = true; 1018e41f4b71Sopenharmony_ci } 1019e41f4b71Sopenharmony_ci }) 1020e41f4b71Sopenharmony_ci 1021e41f4b71Sopenharmony_ci Tabs({ barPosition: BarPosition.Start, index: 0, controller: this.controller }) { 1022e41f4b71Sopenharmony_ci TabContent() { 1023e41f4b71Sopenharmony_ci Column() { 1024e41f4b71Sopenharmony_ci Text(`barOverlap ${this.barOverlap}`).fontSize(16).margin({ top: this.barOverlap ? '56vp' : 0 }) 1025e41f4b71Sopenharmony_ci Text(`barBackgroundColor ${this.barBackgroundColor}`).fontSize(16) 1026e41f4b71Sopenharmony_ci }.width('100%').width('100%').height('100%') 1027e41f4b71Sopenharmony_ci .backgroundColor(Color.Pink) 1028e41f4b71Sopenharmony_ci } 1029e41f4b71Sopenharmony_ci .tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), "1")) 1030e41f4b71Sopenharmony_ci 1031e41f4b71Sopenharmony_ci TabContent() { 1032e41f4b71Sopenharmony_ci Column() { 1033e41f4b71Sopenharmony_ci Text(`barOverlap ${this.barOverlap}`).fontSize(16).margin({ top: this.barOverlap ? '56vp' : 0 }) 1034e41f4b71Sopenharmony_ci Text(`barBackgroundColor ${this.barBackgroundColor}`).fontSize(16) 1035e41f4b71Sopenharmony_ci }.width('100%').width('100%').height('100%') 1036e41f4b71Sopenharmony_ci .backgroundColor(Color.Yellow) 1037e41f4b71Sopenharmony_ci } 1038e41f4b71Sopenharmony_ci .tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), "2")) 1039e41f4b71Sopenharmony_ci 1040e41f4b71Sopenharmony_ci TabContent() { 1041e41f4b71Sopenharmony_ci Column() { 1042e41f4b71Sopenharmony_ci Text(`barOverlap ${this.barOverlap}`).fontSize(16).margin({ top: this.barOverlap ? '56vp' : 0 }) 1043e41f4b71Sopenharmony_ci Text(`barBackgroundColor ${this.barBackgroundColor}`).fontSize(16) 1044e41f4b71Sopenharmony_ci }.width('100%').width('100%').height('100%') 1045e41f4b71Sopenharmony_ci .backgroundColor(Color.Green) 1046e41f4b71Sopenharmony_ci } 1047e41f4b71Sopenharmony_ci .tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), "3")) 1048e41f4b71Sopenharmony_ci } 1049e41f4b71Sopenharmony_ci .vertical(false) 1050e41f4b71Sopenharmony_ci .barMode(BarMode.Fixed) 1051e41f4b71Sopenharmony_ci .height('60%') 1052e41f4b71Sopenharmony_ci .barOverlap(this.barOverlap) 1053e41f4b71Sopenharmony_ci .scrollable(true) 1054e41f4b71Sopenharmony_ci .animationDuration(10) 1055e41f4b71Sopenharmony_ci .barBackgroundColor(this.barBackgroundColor) 1056e41f4b71Sopenharmony_ci } 1057e41f4b71Sopenharmony_ci .height(500) 1058e41f4b71Sopenharmony_ci .padding({ top: '24vp', left: '24vp', right: '24vp' }) 1059e41f4b71Sopenharmony_ci } 1060e41f4b71Sopenharmony_ci} 1061e41f4b71Sopenharmony_ci``` 1062e41f4b71Sopenharmony_ci 1063e41f4b71Sopenharmony_ci 1064e41f4b71Sopenharmony_ci 1065e41f4b71Sopenharmony_ci### Example 5 1066e41f4b71Sopenharmony_ci 1067e41f4b71Sopenharmony_ciThis example uses **barGridAlign** to set the visible area of the tab bar in grid mode. 1068e41f4b71Sopenharmony_ci 1069e41f4b71Sopenharmony_ci```ts 1070e41f4b71Sopenharmony_ci// xxx.ets 1071e41f4b71Sopenharmony_ci@Entry 1072e41f4b71Sopenharmony_ci@Component 1073e41f4b71Sopenharmony_cistruct TabsExample5 { 1074e41f4b71Sopenharmony_ci private controller: TabsController = new TabsController() 1075e41f4b71Sopenharmony_ci @State gridMargin: number = 10 1076e41f4b71Sopenharmony_ci @State gridGutter: number = 10 1077e41f4b71Sopenharmony_ci @State sm: number = -2 1078e41f4b71Sopenharmony_ci @State clickedContent: string = ""; 1079e41f4b71Sopenharmony_ci 1080e41f4b71Sopenharmony_ci build() { 1081e41f4b71Sopenharmony_ci Column() { 1082e41f4b71Sopenharmony_ci Row() { 1083e41f4b71Sopenharmony_ci Button("gridMargin+10 " + this.gridMargin) 1084e41f4b71Sopenharmony_ci .width('47%') 1085e41f4b71Sopenharmony_ci .height(50) 1086e41f4b71Sopenharmony_ci .margin({ top: 5 }) 1087e41f4b71Sopenharmony_ci .onClick((event?: ClickEvent) => { 1088e41f4b71Sopenharmony_ci this.gridMargin += 10 1089e41f4b71Sopenharmony_ci }) 1090e41f4b71Sopenharmony_ci .margin({ right: '6%', bottom: '12vp' }) 1091e41f4b71Sopenharmony_ci Button("gridMargin-10 " + this.gridMargin) 1092e41f4b71Sopenharmony_ci .width('47%') 1093e41f4b71Sopenharmony_ci .height(50) 1094e41f4b71Sopenharmony_ci .margin({ top: 5 }) 1095e41f4b71Sopenharmony_ci .onClick((event?: ClickEvent) => { 1096e41f4b71Sopenharmony_ci this.gridMargin -= 10 1097e41f4b71Sopenharmony_ci }) 1098e41f4b71Sopenharmony_ci .margin({ bottom: '12vp' }) 1099e41f4b71Sopenharmony_ci } 1100e41f4b71Sopenharmony_ci 1101e41f4b71Sopenharmony_ci Row() { 1102e41f4b71Sopenharmony_ci Button("gridGutter+10 " + this.gridGutter) 1103e41f4b71Sopenharmony_ci .width('47%') 1104e41f4b71Sopenharmony_ci .height(50) 1105e41f4b71Sopenharmony_ci .margin({ top: 5 }) 1106e41f4b71Sopenharmony_ci .onClick((event?: ClickEvent) => { 1107e41f4b71Sopenharmony_ci this.gridGutter += 10 1108e41f4b71Sopenharmony_ci }) 1109e41f4b71Sopenharmony_ci .margin({ right: '6%', bottom: '12vp' }) 1110e41f4b71Sopenharmony_ci Button("gridGutter-10 " + this.gridGutter) 1111e41f4b71Sopenharmony_ci .width('47%') 1112e41f4b71Sopenharmony_ci .height(50) 1113e41f4b71Sopenharmony_ci .margin({ top: 5 }) 1114e41f4b71Sopenharmony_ci .onClick((event?: ClickEvent) => { 1115e41f4b71Sopenharmony_ci this.gridGutter -= 10 1116e41f4b71Sopenharmony_ci }) 1117e41f4b71Sopenharmony_ci .margin({ bottom: '12vp' }) 1118e41f4b71Sopenharmony_ci } 1119e41f4b71Sopenharmony_ci 1120e41f4b71Sopenharmony_ci Row() { 1121e41f4b71Sopenharmony_ci Button("sm+2 " + this.sm) 1122e41f4b71Sopenharmony_ci .width('47%') 1123e41f4b71Sopenharmony_ci .height(50) 1124e41f4b71Sopenharmony_ci .margin({ top: 5 }) 1125e41f4b71Sopenharmony_ci .onClick((event?: ClickEvent) => { 1126e41f4b71Sopenharmony_ci this.sm += 2 1127e41f4b71Sopenharmony_ci }) 1128e41f4b71Sopenharmony_ci .margin({ right: '6%' }) 1129e41f4b71Sopenharmony_ci Button("sm-2 " + this.sm).width('47%').height(50).margin({ top: 5 }) 1130e41f4b71Sopenharmony_ci .onClick((event?: ClickEvent) => { 1131e41f4b71Sopenharmony_ci this.sm -= 2 1132e41f4b71Sopenharmony_ci }) 1133e41f4b71Sopenharmony_ci } 1134e41f4b71Sopenharmony_ci 1135e41f4b71Sopenharmony_ci Text ("Tab clicks: "+ this.clickedContent).width ('100%').height (200).margin ({ top: 5 }) 1136e41f4b71Sopenharmony_ci 1137e41f4b71Sopenharmony_ci 1138e41f4b71Sopenharmony_ci Tabs({ barPosition: BarPosition.End, controller: this.controller }) { 1139e41f4b71Sopenharmony_ci TabContent() { 1140e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Pink) 1141e41f4b71Sopenharmony_ci }.tabBar(BottomTabBarStyle.of($r("sys.media.ohos_app_icon"), "1")) 1142e41f4b71Sopenharmony_ci 1143e41f4b71Sopenharmony_ci TabContent() { 1144e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Green) 1145e41f4b71Sopenharmony_ci }.tabBar(BottomTabBarStyle.of($r("sys.media.ohos_app_icon"), "2")) 1146e41f4b71Sopenharmony_ci 1147e41f4b71Sopenharmony_ci TabContent() { 1148e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Blue) 1149e41f4b71Sopenharmony_ci }.tabBar(BottomTabBarStyle.of($r("sys.media.ohos_app_icon"), "3")) 1150e41f4b71Sopenharmony_ci } 1151e41f4b71Sopenharmony_ci .width('350vp') 1152e41f4b71Sopenharmony_ci .animationDuration(300) 1153e41f4b71Sopenharmony_ci .height('60%') 1154e41f4b71Sopenharmony_ci .barGridAlign({ sm: this.sm, margin: this.gridMargin, gutter: this.gridGutter }) 1155e41f4b71Sopenharmony_ci .backgroundColor(0xf1f3f5) 1156e41f4b71Sopenharmony_ci .onTabBarClick((index: number) => { 1157e41f4b71Sopenharmony_ci this.clickedContent += "index " + index + " was clicked\n"; 1158e41f4b71Sopenharmony_ci }) 1159e41f4b71Sopenharmony_ci } 1160e41f4b71Sopenharmony_ci .width('100%') 1161e41f4b71Sopenharmony_ci .height(500) 1162e41f4b71Sopenharmony_ci .margin({ top: 5 }) 1163e41f4b71Sopenharmony_ci .padding('10vp') 1164e41f4b71Sopenharmony_ci } 1165e41f4b71Sopenharmony_ci} 1166e41f4b71Sopenharmony_ci``` 1167e41f4b71Sopenharmony_ci 1168e41f4b71Sopenharmony_ci 1169e41f4b71Sopenharmony_ci 1170e41f4b71Sopenharmony_ci### Example 6 1171e41f4b71Sopenharmony_ci 1172e41f4b71Sopenharmony_ciThis example implements the **ScrollableBarModeOptions** parameter of **barMode**. This parameter is effective only in **Scrollable** mode. 1173e41f4b71Sopenharmony_ci 1174e41f4b71Sopenharmony_ci```ts 1175e41f4b71Sopenharmony_ci// xxx.ets 1176e41f4b71Sopenharmony_ci@Entry 1177e41f4b71Sopenharmony_ci@Component 1178e41f4b71Sopenharmony_cistruct TabsExample6 { 1179e41f4b71Sopenharmony_ci private controller: TabsController = new TabsController() 1180e41f4b71Sopenharmony_ci @State scrollMargin: number = 0 1181e41f4b71Sopenharmony_ci @State layoutStyle: LayoutStyle = LayoutStyle.ALWAYS_CENTER 1182e41f4b71Sopenharmony_ci @State text: string = "Text" 1183e41f4b71Sopenharmony_ci 1184e41f4b71Sopenharmony_ci build() { 1185e41f4b71Sopenharmony_ci Column() { 1186e41f4b71Sopenharmony_ci Row() { 1187e41f4b71Sopenharmony_ci Button("scrollMargin+10 " + this.scrollMargin) 1188e41f4b71Sopenharmony_ci .width('47%') 1189e41f4b71Sopenharmony_ci .height(50) 1190e41f4b71Sopenharmony_ci .margin({ top: 5 }) 1191e41f4b71Sopenharmony_ci .onClick((event?: ClickEvent) => { 1192e41f4b71Sopenharmony_ci this.scrollMargin += 10 1193e41f4b71Sopenharmony_ci }) 1194e41f4b71Sopenharmony_ci .margin({ right: '6%', bottom: '12vp' }) 1195e41f4b71Sopenharmony_ci Button("scrollMargin-10 " + this.scrollMargin) 1196e41f4b71Sopenharmony_ci .width('47%') 1197e41f4b71Sopenharmony_ci .height(50) 1198e41f4b71Sopenharmony_ci .margin({ top: 5 }) 1199e41f4b71Sopenharmony_ci .onClick((event?: ClickEvent) => { 1200e41f4b71Sopenharmony_ci this.scrollMargin -= 10 1201e41f4b71Sopenharmony_ci }) 1202e41f4b71Sopenharmony_ci .margin({ bottom: '12vp' }) 1203e41f4b71Sopenharmony_ci } 1204e41f4b71Sopenharmony_ci 1205e41f4b71Sopenharmony_ci Row() { 1206e41f4b71Sopenharmony_ci Button ("Add Text") 1207e41f4b71Sopenharmony_ci .width('47%') 1208e41f4b71Sopenharmony_ci .height(50) 1209e41f4b71Sopenharmony_ci .margin({ top: 5 }) 1210e41f4b71Sopenharmony_ci .onClick((event?: ClickEvent) => { 1211e41f4b71Sopenharmony_ci this.text += 'Add Text' 1212e41f4b71Sopenharmony_ci }) 1213e41f4b71Sopenharmony_ci .margin({ right: '6%', bottom: '12vp' }) 1214e41f4b71Sopenharmony_ci Button ("Reset Text") 1215e41f4b71Sopenharmony_ci .width('47%') 1216e41f4b71Sopenharmony_ci .height(50) 1217e41f4b71Sopenharmony_ci .margin({ top: 5 }) 1218e41f4b71Sopenharmony_ci .onClick((event?: ClickEvent) => { 1219e41f4b71Sopenharmony_ci this.text = "Text" 1220e41f4b71Sopenharmony_ci }) 1221e41f4b71Sopenharmony_ci .margin({ bottom: '12vp' }) 1222e41f4b71Sopenharmony_ci } 1223e41f4b71Sopenharmony_ci 1224e41f4b71Sopenharmony_ci Row() { 1225e41f4b71Sopenharmony_ci Button("layoutStyle.ALWAYS_CENTER") 1226e41f4b71Sopenharmony_ci .width('100%') 1227e41f4b71Sopenharmony_ci .height(50) 1228e41f4b71Sopenharmony_ci .margin({ top: 5 }) 1229e41f4b71Sopenharmony_ci .fontSize(15) 1230e41f4b71Sopenharmony_ci .onClick((event?: ClickEvent) => { 1231e41f4b71Sopenharmony_ci this.layoutStyle = LayoutStyle.ALWAYS_CENTER; 1232e41f4b71Sopenharmony_ci }) 1233e41f4b71Sopenharmony_ci .margin({ bottom: '12vp' }) 1234e41f4b71Sopenharmony_ci } 1235e41f4b71Sopenharmony_ci 1236e41f4b71Sopenharmony_ci Row() { 1237e41f4b71Sopenharmony_ci Button("layoutStyle.ALWAYS_AVERAGE_SPLIT") 1238e41f4b71Sopenharmony_ci .width('100%') 1239e41f4b71Sopenharmony_ci .height(50) 1240e41f4b71Sopenharmony_ci .margin({ top: 5 }) 1241e41f4b71Sopenharmony_ci .fontSize(15) 1242e41f4b71Sopenharmony_ci .onClick((event?: ClickEvent) => { 1243e41f4b71Sopenharmony_ci this.layoutStyle = LayoutStyle.ALWAYS_AVERAGE_SPLIT; 1244e41f4b71Sopenharmony_ci }) 1245e41f4b71Sopenharmony_ci .margin({ bottom: '12vp' }) 1246e41f4b71Sopenharmony_ci } 1247e41f4b71Sopenharmony_ci 1248e41f4b71Sopenharmony_ci Row() { 1249e41f4b71Sopenharmony_ci Button("layoutStyle.SPACE_BETWEEN_OR_CENTER") 1250e41f4b71Sopenharmony_ci .width('100%') 1251e41f4b71Sopenharmony_ci .height(50) 1252e41f4b71Sopenharmony_ci .margin({ top: 5 }) 1253e41f4b71Sopenharmony_ci .fontSize(15) 1254e41f4b71Sopenharmony_ci .onClick((event?: ClickEvent) => { 1255e41f4b71Sopenharmony_ci this.layoutStyle = LayoutStyle.SPACE_BETWEEN_OR_CENTER; 1256e41f4b71Sopenharmony_ci }) 1257e41f4b71Sopenharmony_ci .margin({ bottom: '12vp' }) 1258e41f4b71Sopenharmony_ci } 1259e41f4b71Sopenharmony_ci 1260e41f4b71Sopenharmony_ci Tabs({ barPosition: BarPosition.End, controller: this.controller }) { 1261e41f4b71Sopenharmony_ci TabContent() { 1262e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Pink) 1263e41f4b71Sopenharmony_ci }.tabBar(SubTabBarStyle.of(this.text)) 1264e41f4b71Sopenharmony_ci 1265e41f4b71Sopenharmony_ci TabContent() { 1266e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Green) 1267e41f4b71Sopenharmony_ci }.tabBar(SubTabBarStyle.of(this.text)) 1268e41f4b71Sopenharmony_ci 1269e41f4b71Sopenharmony_ci TabContent() { 1270e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor(Color.Blue) 1271e41f4b71Sopenharmony_ci }.tabBar(SubTabBarStyle.of(this.text)) 1272e41f4b71Sopenharmony_ci } 1273e41f4b71Sopenharmony_ci .animationDuration(300) 1274e41f4b71Sopenharmony_ci .height('60%') 1275e41f4b71Sopenharmony_ci .backgroundColor(0xf1f3f5) 1276e41f4b71Sopenharmony_ci .barMode(BarMode.Scrollable, { margin: this.scrollMargin, nonScrollableLayoutStyle: this.layoutStyle }) 1277e41f4b71Sopenharmony_ci } 1278e41f4b71Sopenharmony_ci .width('100%') 1279e41f4b71Sopenharmony_ci .height(500) 1280e41f4b71Sopenharmony_ci .margin({ top: 5 }) 1281e41f4b71Sopenharmony_ci .padding('24vp') 1282e41f4b71Sopenharmony_ci } 1283e41f4b71Sopenharmony_ci} 1284e41f4b71Sopenharmony_ci``` 1285e41f4b71Sopenharmony_ci 1286e41f4b71Sopenharmony_ci 1287e41f4b71Sopenharmony_ci 1288e41f4b71Sopenharmony_ci### Example 7 1289e41f4b71Sopenharmony_ci 1290e41f4b71Sopenharmony_ciThis example uses **customContentTransition** to implement a custom tab switching animation. 1291e41f4b71Sopenharmony_ci 1292e41f4b71Sopenharmony_ci```ts 1293e41f4b71Sopenharmony_ci// xxx.ets 1294e41f4b71Sopenharmony_ciinterface itemType { 1295e41f4b71Sopenharmony_ci text: string, 1296e41f4b71Sopenharmony_ci backgroundColor: Color 1297e41f4b71Sopenharmony_ci} 1298e41f4b71Sopenharmony_ci 1299e41f4b71Sopenharmony_ci@Entry 1300e41f4b71Sopenharmony_ci@Component 1301e41f4b71Sopenharmony_cistruct TabsCustomAnimationExample { 1302e41f4b71Sopenharmony_ci @State data: itemType[] = [ 1303e41f4b71Sopenharmony_ci { 1304e41f4b71Sopenharmony_ci text: 'Red', 1305e41f4b71Sopenharmony_ci backgroundColor: Color.Red 1306e41f4b71Sopenharmony_ci }, 1307e41f4b71Sopenharmony_ci { 1308e41f4b71Sopenharmony_ci text: 'Yellow', 1309e41f4b71Sopenharmony_ci backgroundColor: Color.Yellow 1310e41f4b71Sopenharmony_ci }, 1311e41f4b71Sopenharmony_ci { 1312e41f4b71Sopenharmony_ci text: 'Blue', 1313e41f4b71Sopenharmony_ci backgroundColor: Color.Blue 1314e41f4b71Sopenharmony_ci }] 1315e41f4b71Sopenharmony_ci @State opacityList: number[] = [] 1316e41f4b71Sopenharmony_ci @State scaleList: number[] = [] 1317e41f4b71Sopenharmony_ci 1318e41f4b71Sopenharmony_ci private durationList: number[] = [] 1319e41f4b71Sopenharmony_ci private timeoutList: number[] = [] 1320e41f4b71Sopenharmony_ci private customContentTransition: (from: number, to: number) => TabContentAnimatedTransition = (from: number, to: number) => { 1321e41f4b71Sopenharmony_ci let tabContentAnimatedTransition = { 1322e41f4b71Sopenharmony_ci timeout: this.timeoutList[from], 1323e41f4b71Sopenharmony_ci transition: (proxy: TabContentTransitionProxy) => { 1324e41f4b71Sopenharmony_ci this.scaleList[from] = 1.0 1325e41f4b71Sopenharmony_ci this.scaleList[to] = 0.5 1326e41f4b71Sopenharmony_ci this.opacityList[from] = 1.0 1327e41f4b71Sopenharmony_ci this.opacityList[to] = 0.5 1328e41f4b71Sopenharmony_ci animateTo({ 1329e41f4b71Sopenharmony_ci duration: this.durationList[from], 1330e41f4b71Sopenharmony_ci onFinish: () => { 1331e41f4b71Sopenharmony_ci proxy.finishTransition() 1332e41f4b71Sopenharmony_ci } 1333e41f4b71Sopenharmony_ci }, () => { 1334e41f4b71Sopenharmony_ci this.scaleList[from] = 0.5 1335e41f4b71Sopenharmony_ci this.scaleList[to] = 1.0 1336e41f4b71Sopenharmony_ci this.opacityList[from] = 0.5 1337e41f4b71Sopenharmony_ci this.opacityList[to] = 1.0 1338e41f4b71Sopenharmony_ci }) 1339e41f4b71Sopenharmony_ci } 1340e41f4b71Sopenharmony_ci } as TabContentAnimatedTransition 1341e41f4b71Sopenharmony_ci return tabContentAnimatedTransition 1342e41f4b71Sopenharmony_ci } 1343e41f4b71Sopenharmony_ci 1344e41f4b71Sopenharmony_ci aboutToAppear(): void { 1345e41f4b71Sopenharmony_ci let duration = 1000 1346e41f4b71Sopenharmony_ci let timeout = 1000 1347e41f4b71Sopenharmony_ci for (let i = 1; i <= this.data.length; i++) { 1348e41f4b71Sopenharmony_ci this.opacityList.push(1.0) 1349e41f4b71Sopenharmony_ci this.scaleList.push(1.0) 1350e41f4b71Sopenharmony_ci this.durationList.push(duration * i) 1351e41f4b71Sopenharmony_ci this.timeoutList.push(timeout * i) 1352e41f4b71Sopenharmony_ci } 1353e41f4b71Sopenharmony_ci } 1354e41f4b71Sopenharmony_ci 1355e41f4b71Sopenharmony_ci build() { 1356e41f4b71Sopenharmony_ci Column() { 1357e41f4b71Sopenharmony_ci Tabs() { 1358e41f4b71Sopenharmony_ci ForEach(this.data, (item: itemType, index: number) => { 1359e41f4b71Sopenharmony_ci TabContent() {} 1360e41f4b71Sopenharmony_ci .tabBar(item.text) 1361e41f4b71Sopenharmony_ci .backgroundColor(item.backgroundColor) 1362e41f4b71Sopenharmony_ci // Customize the opacity and scale animation. 1363e41f4b71Sopenharmony_ci .opacity(this.opacityList[index]) 1364e41f4b71Sopenharmony_ci .scale({ x: this.scaleList[index], y: this.scaleList[index] }) 1365e41f4b71Sopenharmony_ci }) 1366e41f4b71Sopenharmony_ci } 1367e41f4b71Sopenharmony_ci .backgroundColor(0xf1f3f5) 1368e41f4b71Sopenharmony_ci .width('100%') 1369e41f4b71Sopenharmony_ci .height(500) 1370e41f4b71Sopenharmony_ci .customContentTransition(this.customContentTransition) 1371e41f4b71Sopenharmony_ci } 1372e41f4b71Sopenharmony_ci } 1373e41f4b71Sopenharmony_ci} 1374e41f4b71Sopenharmony_ci``` 1375e41f4b71Sopenharmony_ci 1376e41f4b71Sopenharmony_ci 1377e41f4b71Sopenharmony_ci### Example 8 1378e41f4b71Sopenharmony_ci 1379e41f4b71Sopenharmony_ciThis example uses **onContentWillChange** to switch to a new page on swiping. 1380e41f4b71Sopenharmony_ci 1381e41f4b71Sopenharmony_ci```ts 1382e41f4b71Sopenharmony_ci//xxx.ets 1383e41f4b71Sopenharmony_ci@Entry 1384e41f4b71Sopenharmony_ci@Component 1385e41f4b71Sopenharmony_cistruct TabsExample { 1386e41f4b71Sopenharmony_ci @State currentIndex: number = 2 1387e41f4b71Sopenharmony_ci private controller: TabsController = new TabsController() 1388e41f4b71Sopenharmony_ci @Builder tabBuilder(title: string,targetIndex: number) { 1389e41f4b71Sopenharmony_ci Column(){ 1390e41f4b71Sopenharmony_ci Text(title).fontColor(this.currentIndex === targetIndex ? '#1698CE' : '#6B6B6B') 1391e41f4b71Sopenharmony_ci }.width('100%') 1392e41f4b71Sopenharmony_ci .height(50) 1393e41f4b71Sopenharmony_ci .justifyContent(FlexAlign.Center) 1394e41f4b71Sopenharmony_ci } 1395e41f4b71Sopenharmony_ci build() { 1396e41f4b71Sopenharmony_ci Column() { 1397e41f4b71Sopenharmony_ci Tabs({ barPosition: BarPosition.End, controller: this.controller, index: this.currentIndex }) { 1398e41f4b71Sopenharmony_ci TabContent() { 1399e41f4b71Sopenharmony_ci Column(){ 1400e41f4b71Sopenharmony_ci Text('Content of the Home tab') 1401e41f4b71Sopenharmony_ci }.width('100%').height('100%').backgroundColor('#00CB87').justifyContent(FlexAlign.Center) 1402e41f4b71Sopenharmony_ci }.tabBar(this.tabBuilder('Home',0)) 1403e41f4b71Sopenharmony_ci 1404e41f4b71Sopenharmony_ci TabContent() { 1405e41f4b71Sopenharmony_ci Column(){ 1406e41f4b71Sopenharmony_ci Text('Content of the Discover tab') 1407e41f4b71Sopenharmony_ci }.width('100%').height('100%').backgroundColor('#007DFF').justifyContent(FlexAlign.Center) 1408e41f4b71Sopenharmony_ci }.tabBar (this.tabBuilder ('Discover', 1)) 1409e41f4b71Sopenharmony_ci 1410e41f4b71Sopenharmony_ci TabContent() { 1411e41f4b71Sopenharmony_ci Column(){ 1412e41f4b71Sopenharmony_ci Text('Content of the Recommended tab') 1413e41f4b71Sopenharmony_ci }.width('100%').height('100%').backgroundColor('#FFBF00').justifyContent(FlexAlign.Center) 1414e41f4b71Sopenharmony_ci }.tabBar (this.tabBuilder ('Recommended', 2)) 1415e41f4b71Sopenharmony_ci 1416e41f4b71Sopenharmony_ci TabContent() { 1417e41f4b71Sopenharmony_ci Column(){ 1418e41f4b71Sopenharmony_ci Text('Content of the Me tab') 1419e41f4b71Sopenharmony_ci }.width('100%').height('100%').backgroundColor('#E67C92').justifyContent(FlexAlign.Center) 1420e41f4b71Sopenharmony_ci }.tabBar(this.tabBuilder('Me',3)) 1421e41f4b71Sopenharmony_ci } 1422e41f4b71Sopenharmony_ci .vertical(false) 1423e41f4b71Sopenharmony_ci .barMode(BarMode.Fixed) 1424e41f4b71Sopenharmony_ci .barWidth(360) 1425e41f4b71Sopenharmony_ci .barHeight(60) 1426e41f4b71Sopenharmony_ci .animationDuration(0) 1427e41f4b71Sopenharmony_ci .onChange((index: number) => { 1428e41f4b71Sopenharmony_ci this.currentIndex = index 1429e41f4b71Sopenharmony_ci }) 1430e41f4b71Sopenharmony_ci .width(360) 1431e41f4b71Sopenharmony_ci .height(600) 1432e41f4b71Sopenharmony_ci .backgroundColor('#F1F3F5') 1433e41f4b71Sopenharmony_ci .scrollable(true) 1434e41f4b71Sopenharmony_ci .onContentWillChange((currentIndex, comingIndex) => { 1435e41f4b71Sopenharmony_ci if (comingIndex == 2) { 1436e41f4b71Sopenharmony_ci return false 1437e41f4b71Sopenharmony_ci } 1438e41f4b71Sopenharmony_ci return true 1439e41f4b71Sopenharmony_ci }) 1440e41f4b71Sopenharmony_ci 1441e41f4b71Sopenharmony_ci Button('Change Index').width('50%').margin({ top: 20 }) 1442e41f4b71Sopenharmony_ci .onClick(()=>{ 1443e41f4b71Sopenharmony_ci this.currentIndex = (this.currentIndex + 1) % 4 1444e41f4b71Sopenharmony_ci }) 1445e41f4b71Sopenharmony_ci 1446e41f4b71Sopenharmony_ci Button('changeIndex').width('50%').margin({ top: 20 }) 1447e41f4b71Sopenharmony_ci .onClick(()=>{ 1448e41f4b71Sopenharmony_ci this.currentIndex = (this.currentIndex + 1) % 4 1449e41f4b71Sopenharmony_ci this.controller.changeIndex(this.currentIndex) 1450e41f4b71Sopenharmony_ci }) 1451e41f4b71Sopenharmony_ci }.width('100%') 1452e41f4b71Sopenharmony_ci } 1453e41f4b71Sopenharmony_ci} 1454e41f4b71Sopenharmony_ci``` 1455e41f4b71Sopenharmony_ci 1456e41f4b71Sopenharmony_ci 1457e41f4b71Sopenharmony_ci### Example 9 1458e41f4b71Sopenharmony_ci 1459e41f4b71Sopenharmony_ciThis example uses **onChange**, **onAnimationStart**, **onAnimationEnd**, and **onGestureSwipe** APIs to customize the tab bar switching animation. 1460e41f4b71Sopenharmony_ci 1461e41f4b71Sopenharmony_ci```ts 1462e41f4b71Sopenharmony_ci// xxx.ets 1463e41f4b71Sopenharmony_ciimport { ComponentUtils } from '@kit.ArkUI' 1464e41f4b71Sopenharmony_ci 1465e41f4b71Sopenharmony_ci@Entry 1466e41f4b71Sopenharmony_ci@Component 1467e41f4b71Sopenharmony_cistruct TabsExample { 1468e41f4b71Sopenharmony_ci @State currentIndex: number = 0 1469e41f4b71Sopenharmony_ci @State animationDuration: number = 300 1470e41f4b71Sopenharmony_ci @State indicatorLeftMargin: number = 0 1471e41f4b71Sopenharmony_ci @State indicatorWidth: number = 0 1472e41f4b71Sopenharmony_ci private tabsWidth: number = 0 1473e41f4b71Sopenharmony_ci private componentUtils: ComponentUtils = this.getUIContext().getComponentUtils() 1474e41f4b71Sopenharmony_ci 1475e41f4b71Sopenharmony_ci @Builder 1476e41f4b71Sopenharmony_ci tabBuilder(index: number, name: string) { 1477e41f4b71Sopenharmony_ci Column() { 1478e41f4b71Sopenharmony_ci Text(name) 1479e41f4b71Sopenharmony_ci .fontSize(16) 1480e41f4b71Sopenharmony_ci .fontColor(this.currentIndex === index ? '#007DFF' : '#182431') 1481e41f4b71Sopenharmony_ci .fontWeight(this.currentIndex === index ? 500 : 400) 1482e41f4b71Sopenharmony_ci .id(index.toString()) 1483e41f4b71Sopenharmony_ci .onAreaChange((oldValue: Area,newValue: Area) => { 1484e41f4b71Sopenharmony_ci if (this.currentIndex === index && (this.indicatorLeftMargin === 0 || this.indicatorWidth === 0)){ 1485e41f4b71Sopenharmony_ci if (newValue.position.x != undefined) { 1486e41f4b71Sopenharmony_ci let positionX = Number.parseFloat(newValue.position.x.toString()) 1487e41f4b71Sopenharmony_ci this.indicatorLeftMargin = Number.isNaN(positionX) ? 0 : positionX 1488e41f4b71Sopenharmony_ci } 1489e41f4b71Sopenharmony_ci let width = Number.parseFloat(newValue.width.toString()) 1490e41f4b71Sopenharmony_ci this.indicatorWidth = Number.isNaN(width) ? 0 : width 1491e41f4b71Sopenharmony_ci } 1492e41f4b71Sopenharmony_ci }) 1493e41f4b71Sopenharmony_ci }.width('100%') 1494e41f4b71Sopenharmony_ci } 1495e41f4b71Sopenharmony_ci 1496e41f4b71Sopenharmony_ci build() { 1497e41f4b71Sopenharmony_ci Stack({ alignContent: Alignment.TopStart }) { 1498e41f4b71Sopenharmony_ci Tabs({ barPosition: BarPosition.Start }) { 1499e41f4b71Sopenharmony_ci TabContent() { 1500e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor('#00CB87') 1501e41f4b71Sopenharmony_ci }.tabBar(this.tabBuilder(0, 'green')) 1502e41f4b71Sopenharmony_ci 1503e41f4b71Sopenharmony_ci TabContent() { 1504e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor('#007DFF') 1505e41f4b71Sopenharmony_ci }.tabBar(this.tabBuilder(1, 'blue')) 1506e41f4b71Sopenharmony_ci 1507e41f4b71Sopenharmony_ci TabContent() { 1508e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor('#FFBF00') 1509e41f4b71Sopenharmony_ci }.tabBar(this.tabBuilder(2, 'yellow')) 1510e41f4b71Sopenharmony_ci 1511e41f4b71Sopenharmony_ci TabContent() { 1512e41f4b71Sopenharmony_ci Column().width('100%').height('100%').backgroundColor('#E67C92') 1513e41f4b71Sopenharmony_ci }.tabBar(this.tabBuilder(3, 'pink')) 1514e41f4b71Sopenharmony_ci } 1515e41f4b71Sopenharmony_ci .onAreaChange((oldValue: Area,newValue: Area)=> { 1516e41f4b71Sopenharmony_ci let width = Number.parseFloat(newValue.width.toString()) 1517e41f4b71Sopenharmony_ci this.tabsWidth = Number.isNaN(width) ? 0 : width 1518e41f4b71Sopenharmony_ci }) 1519e41f4b71Sopenharmony_ci .barWidth('100%') 1520e41f4b71Sopenharmony_ci .barHeight(56) 1521e41f4b71Sopenharmony_ci .width('100%') 1522e41f4b71Sopenharmony_ci .height(296) 1523e41f4b71Sopenharmony_ci .backgroundColor('#F1F3F5') 1524e41f4b71Sopenharmony_ci .animationDuration(this.animationDuration) 1525e41f4b71Sopenharmony_ci .onChange((index: number) => { 1526e41f4b71Sopenharmony_ci this.currentIndex = index // Listen for index changes to switch the tab page content. 1527e41f4b71Sopenharmony_ci }) 1528e41f4b71Sopenharmony_ci .onAnimationStart((index: number, targetIndex: number, event: TabsAnimationEvent) => { 1529e41f4b71Sopenharmony_ci // Triggered when the tab switching animation starts. The underline moves with the active tab, along with a width gradient. 1530e41f4b71Sopenharmony_ci this.currentIndex = targetIndex 1531e41f4b71Sopenharmony_ci let targetIndexInfo = this.getTextInfo(targetIndex) 1532e41f4b71Sopenharmony_ci this.startAnimateTo(this.animationDuration, targetIndexInfo.left, targetIndexInfo.width) 1533e41f4b71Sopenharmony_ci }) 1534e41f4b71Sopenharmony_ci .onAnimationEnd((index: number,event: TabsAnimationEvent) => { 1535e41f4b71Sopenharmony_ci // Triggered when the tab switching animation ends. The underline animation stops. 1536e41f4b71Sopenharmony_ci let currentIndicatorInfo = this.getCurrentIndicatorInfo(index,event) 1537e41f4b71Sopenharmony_ci this.startAnimateTo(0,currentIndicatorInfo.left,currentIndicatorInfo.width) 1538e41f4b71Sopenharmony_ci }) 1539e41f4b71Sopenharmony_ci .onGestureSwipe((index: number,event: TabsAnimationEvent) => { 1540e41f4b71Sopenharmony_ci // Triggered on a frame-by-frame basis when the tab is switched by a swipe. 1541e41f4b71Sopenharmony_ci let currentIndicatorInfo = this.getCurrentIndicatorInfo(index,event) 1542e41f4b71Sopenharmony_ci this.currentIndex = currentIndicatorInfo.index 1543e41f4b71Sopenharmony_ci this.indicatorLeftMargin = currentIndicatorInfo.left 1544e41f4b71Sopenharmony_ci this.indicatorWidth = currentIndicatorInfo.width 1545e41f4b71Sopenharmony_ci }) 1546e41f4b71Sopenharmony_ci 1547e41f4b71Sopenharmony_ci Column() 1548e41f4b71Sopenharmony_ci .height(2) 1549e41f4b71Sopenharmony_ci .width(this.indicatorWidth) 1550e41f4b71Sopenharmony_ci .margin({ left: this.indicatorLeftMargin, top:48}) 1551e41f4b71Sopenharmony_ci .backgroundColor('#007DFF') 1552e41f4b71Sopenharmony_ci }.width('100%') 1553e41f4b71Sopenharmony_ci } 1554e41f4b71Sopenharmony_ci 1555e41f4b71Sopenharmony_ci private getTextInfo(index: number): Record<string, number> { 1556e41f4b71Sopenharmony_ci let rectangle = this.componentUtils.getRectangleById(index.toString()) 1557e41f4b71Sopenharmony_ci return { 'left': px2vp(rectangle.windowOffset.x), 'width': px2vp(rectangle.size.width) } 1558e41f4b71Sopenharmony_ci } 1559e41f4b71Sopenharmony_ci 1560e41f4b71Sopenharmony_ci private getCurrentIndicatorInfo(index: number, event: TabsAnimationEvent): Record<string, number> { 1561e41f4b71Sopenharmony_ci let nextIndex = index 1562e41f4b71Sopenharmony_ci if (index > 0 && event.currentOffset > 0) { 1563e41f4b71Sopenharmony_ci nextIndex-- 1564e41f4b71Sopenharmony_ci } else if (index < 3 && event.currentOffset < 0) { 1565e41f4b71Sopenharmony_ci nextIndex++ 1566e41f4b71Sopenharmony_ci } 1567e41f4b71Sopenharmony_ci let indexInfo = this.getTextInfo(index) 1568e41f4b71Sopenharmony_ci let nextIndexInfo = this.getTextInfo(nextIndex) 1569e41f4b71Sopenharmony_ci let swipeRatio = Math.abs(event.currentOffset / this.tabsWidth) 1570e41f4b71Sopenharmony_ci let currentIndex = swipeRatio > 0.5 ? nextIndex : index // When the scroll distance exceeds half of the page, the tab bar switches to the next page. 1571e41f4b71Sopenharmony_ci let currentLeft = indexInfo.left + (nextIndexInfo.left - indexInfo.left) * swipeRatio 1572e41f4b71Sopenharmony_ci let currentWidth = indexInfo.width + (nextIndexInfo.width - indexInfo.width) * swipeRatio 1573e41f4b71Sopenharmony_ci return { 'index': currentIndex, 'left': currentLeft, 'width': currentWidth } 1574e41f4b71Sopenharmony_ci } 1575e41f4b71Sopenharmony_ci 1576e41f4b71Sopenharmony_ci private startAnimateTo(duration: number, leftMargin: number, width: number) { 1577e41f4b71Sopenharmony_ci animateTo({ 1578e41f4b71Sopenharmony_ci duration: duration, // Animation duration. 1579e41f4b71Sopenharmony_ci curve: Curve.Linear, // Animation curve. 1580e41f4b71Sopenharmony_ci iterations: 1, // Number of playback times. 1581e41f4b71Sopenharmony_ci playMode: PlayMode.Normal // Animation playback mode. 1582e41f4b71Sopenharmony_ci onFinish: () => { 1583e41f4b71Sopenharmony_ci console.info('play end') 1584e41f4b71Sopenharmony_ci } 1585e41f4b71Sopenharmony_ci }, () => { 1586e41f4b71Sopenharmony_ci this.indicatorLeftMargin = leftMargin 1587e41f4b71Sopenharmony_ci this.indicatorWidth = width 1588e41f4b71Sopenharmony_ci }) 1589e41f4b71Sopenharmony_ci } 1590e41f4b71Sopenharmony_ci} 1591e41f4b71Sopenharmony_ci``` 1592e41f4b71Sopenharmony_ci 1593e41f4b71Sopenharmony_ci 1594e41f4b71Sopenharmony_ci 1595e41f4b71Sopenharmony_ci### Example 10 1596e41f4b71Sopenharmony_ci 1597e41f4b71Sopenharmony_ciIn this example, the **preloadItems** API is used to preload specified child nodes. 1598e41f4b71Sopenharmony_ci 1599e41f4b71Sopenharmony_ci```ts 1600e41f4b71Sopenharmony_ci// xxx.ets 1601e41f4b71Sopenharmony_ciimport { BusinessError } from '@kit.BasicServicesKit' 1602e41f4b71Sopenharmony_ci 1603e41f4b71Sopenharmony_ci@Entry 1604e41f4b71Sopenharmony_ci@Component 1605e41f4b71Sopenharmony_cistruct TabsPreloadItems { 1606e41f4b71Sopenharmony_ci @State currentIndex: number = 1 1607e41f4b71Sopenharmony_ci private tabsController: TabsController = new TabsController() 1608e41f4b71Sopenharmony_ci 1609e41f4b71Sopenharmony_ci build() { 1610e41f4b71Sopenharmony_ci Column() { 1611e41f4b71Sopenharmony_ci Tabs({ index: this.currentIndex, controller: this.tabsController }) { 1612e41f4b71Sopenharmony_ci TabContent() { 1613e41f4b71Sopenharmony_ci MyComponent({ color: '#00CB87' }) 1614e41f4b71Sopenharmony_ci }.tabBar(SubTabBarStyle.of('green')) 1615e41f4b71Sopenharmony_ci 1616e41f4b71Sopenharmony_ci TabContent() { 1617e41f4b71Sopenharmony_ci MyComponent({ color: '#007DFF' }) 1618e41f4b71Sopenharmony_ci }.tabBar(SubTabBarStyle.of('blue')) 1619e41f4b71Sopenharmony_ci 1620e41f4b71Sopenharmony_ci TabContent() { 1621e41f4b71Sopenharmony_ci MyComponent({ color: '#FFBF00' }) 1622e41f4b71Sopenharmony_ci }.tabBar(SubTabBarStyle.of('yellow')) 1623e41f4b71Sopenharmony_ci 1624e41f4b71Sopenharmony_ci TabContent() { 1625e41f4b71Sopenharmony_ci MyComponent({ color: '#E67C92' }) 1626e41f4b71Sopenharmony_ci }.tabBar(SubTabBarStyle.of('pink')) 1627e41f4b71Sopenharmony_ci } 1628e41f4b71Sopenharmony_ci .width(360) 1629e41f4b71Sopenharmony_ci .height(296) 1630e41f4b71Sopenharmony_ci .backgroundColor('#F1F3F5') 1631e41f4b71Sopenharmony_ci .onChange((index: number) => { 1632e41f4b71Sopenharmony_ci this.currentIndex = index 1633e41f4b71Sopenharmony_ci }) 1634e41f4b71Sopenharmony_ci 1635e41f4b71Sopenharmony_ci Button('preload items: [0, 2, 3]') 1636e41f4b71Sopenharmony_ci .margin(5) 1637e41f4b71Sopenharmony_ci .onClick(() => { 1638e41f4b71Sopenharmony_ci // Preload child nodes 0, 2, and 3 to improve the performance when users swipe or click to switch to these nodes. 1639e41f4b71Sopenharmony_ci this.tabsController.preloadItems([0, 2, 3]) 1640e41f4b71Sopenharmony_ci .then(() => { 1641e41f4b71Sopenharmony_ci console.info('preloadItems success.') 1642e41f4b71Sopenharmony_ci }) 1643e41f4b71Sopenharmony_ci .catch((error: BusinessError) => { 1644e41f4b71Sopenharmony_ci console.error('preloadItems failed, error code: ' + error.code + ', error message: ' + error.message) 1645e41f4b71Sopenharmony_ci }) 1646e41f4b71Sopenharmony_ci }) 1647e41f4b71Sopenharmony_ci } 1648e41f4b71Sopenharmony_ci } 1649e41f4b71Sopenharmony_ci} 1650e41f4b71Sopenharmony_ci 1651e41f4b71Sopenharmony_ci@Component 1652e41f4b71Sopenharmony_cistruct MyComponent { 1653e41f4b71Sopenharmony_ci private color: string = "" 1654e41f4b71Sopenharmony_ci 1655e41f4b71Sopenharmony_ci aboutToAppear(): void { 1656e41f4b71Sopenharmony_ci console.info('aboutToAppear backgroundColor:' + this.color) 1657e41f4b71Sopenharmony_ci } 1658e41f4b71Sopenharmony_ci 1659e41f4b71Sopenharmony_ci aboutToDisappear(): void { 1660e41f4b71Sopenharmony_ci console.info('aboutToDisappear backgroundColor:' + this.color) 1661e41f4b71Sopenharmony_ci } 1662e41f4b71Sopenharmony_ci 1663e41f4b71Sopenharmony_ci build() { 1664e41f4b71Sopenharmony_ci Column() 1665e41f4b71Sopenharmony_ci .width('100%') 1666e41f4b71Sopenharmony_ci .height('100%') 1667e41f4b71Sopenharmony_ci .backgroundColor(this.color) 1668e41f4b71Sopenharmony_ci } 1669e41f4b71Sopenharmony_ci} 1670e41f4b71Sopenharmony_ci``` 1671