1# Tabs 2 3 4When there is a large amount of page information, to enable the user to focus on the currently displayed content, the page content needs to be classified to improve the page space utilization. The [Tabs](../reference/arkui-ts/ts-container-tabs.md) component can quickly switch between views on a page, improving information search efficiency and reducing the amount of information that users can obtain at a time. 5 6 7## Basic Layout 8 9 The Tabs component consists of two parts: TabContent and TabBar. TabContent is the content page, and TabBar is the navigation tab bar. The following figure shows the page structure. The layout varies according to the navigation type. TabContent can be classified into bottom navigation, top navigation, and side navigation. The navigation bar is located at the bottom, top, and side, respectively. 10 Figure 1 Tabs component layout 11 12![tabs-layout](figures/tabs-layout.png) 13 14 15>**NOTE** 16> 17> - The **\<TabContent>** component does not support setting of the common width attribute. By default, its width is the same as that of the parent **\<Tabs>** component. 18> 19> - The **\<TabContent>** component does not support setting of the common height attribute. Its height is determined by the height of the parent **\<Tabs>** component and the **\<TabBar>** component. 20 21 22Tabs use braces to enclose TabContent, as shown in Figure 2. TabContent displays the corresponding content page. 23 24 25 Figure 2 Using Tabs and TabContent 26 27![tabs-tabscontent](figures/tabs-tabscontent.png) 28 29 30The content corresponding to each TabContent must have a tab page, which can be configured through the tabBar attribute of TabContent. You can set the tabBar attribute on the TabContent component to set the content on the corresponding tab page. The tabBar functions as the content tab page. 31 32 33 34```ts 35 TabContent() { 36 Text('Homepage content').fontSize(30) 37 } 38.tabBar ('Home') 39``` 40 41 42When setting multiple contents, place them in sequence in Tabs. 43 44 45 46```ts 47Tabs() { 48 TabContent() { 49 Text('Homepage content').fontSize(30) 50 } 51 .tabBar ('Home') 52 53 TabContent() { 54 Text('Recommendation').fontSize(30) 55 } 56 .tabBar ('Recommend') 57 58 TabContent() { 59 Text ('Discovered content').fontSize (30) 60 } 61 .tabBar ('Discovery') 62 63 TabContent() { 64 Text ('My Content').fontSize (30) 65 } 66 .tabBar ("My") 67} 68``` 69 70 71## Bottom navigation 72 73Bottom navigation is the most common navigation mode in applications. The bottom navigation is located at the bottom of the level-1 page of the application. When the user opens the application, the function classification of the entire application and the content corresponding to the tab can be distinguished. In addition, the bottom navigation is located at the bottom of the application, which facilitates one-hand operations of the user. The bottom navigation generally exists as a main navigation form of an application, and a function of the bottom navigation is to classify content that a user cares about according to a function, cater to a use habit of the user, and facilitate content switching between different modules. 74 75 76 Figure 3 Navigation bar at the bottom 77 78![Bottom Navigation](figures/Bottom Navigation.gif) 79 80 81The barPosition parameter of Tabs is used to set the position of the navigation bar. By default, the navigation bar is on the top, and the default value of the barPosition parameter is Start. To set the bottom navigation, you need to transfer parameters in Tabs. Set barPosition to End. 82 83 84```ts 85Tabs({ barPosition: BarPosition.End }) { 86 // TabContent: home page, discovery, recommendation, and my 87 ... 88} 89``` 90 91 92## Top Navigation 93 94When there are many content categories, the probability that users browse different content is similar, and users need to quickly switch between different content categories, the top navigation mode is generally used to further divide the bottom navigation content. Common information applications classify content into attention, video, and digital, alternatively, in a theme application, a theme is further divided into a picture, a video, a font, and the like. 95 96 Figure 4 Navigation bar on the top 97 98![Top Navigation](figures/Top Navigation.gif) 99 100The default barPosition parameter of the Tabs component is Start, indicating the top navigation mode. 101 102 103```ts 104Tabs({ barPosition: BarPosition.Start }) { 105 // TabContent: follow, video, game, digital, technology, sports, and movie 106 ... 107} 108``` 109 110 111## Side Navigation 112 113Side navigation is a navigation mode that is seldom used by applications. It is more applicable to landscape screens and is used to perform navigation operations on applications. Because the visual habit of the user is from left to right, the side navigation bar is the left sidebar by default. 114 115 116 Figure 5 Side navigation bar 117 118![Side Navigation](figures/Side Navigation.png) 119 120 121To implement the side navigation bar, you need to set the vertical attribute of Tabs to true. In the bottom navigation and top navigation implementations, the default value is false, indicating that the content page and navigation bar are arranged vertically. 122 123 124 125```ts 126Tabs({ barPosition: BarPosition.Start }) { 127 // TabContent: home page, discovery, recommendation, and my 128 ... 129} 130.vertical(true) 131.barWidth(100) 132.barHeight(200) 133``` 134 135 136>**NOTE** 137> 138> - When vertical is set to true, the tabbar width fully occupies the screen width by default. You need to set barWidth to a proper value. 139> 140> - If vertical is set to true, the tabbar height is the actual content height by default. You need to set barHeight to a proper value. 141 142 143## Restricting the Slide Switch of the Navigation Bar 144 145 By default, the navigation bar supports sliding. On some pages that require multi-level classification of content information, for example, when the bottom navigation and top navigation are supported, the sliding effect of the bottom navigation bar conflicts with that of the top navigation. In this case, the sliding of the bottom navigation bar needs to be restricted, this prevents poor user experience. 146 Figure 6 Restricting the sliding of the navigation bar at the bottom 147 148![Restricted Navigation](figures/Restricted Navigation.gif) 149 150 151The attribute that controls the sliding switch is scrollable. The default value is true, indicating that the sliding switch is allowed. To restrict the sliding switch, set this parameter to false. 152 153 154 155```ts 156Tabs({ barPosition: BarPosition.End }) { 157 TabContent(){ 158 Column(){ 159 Tabs(){ 160 //Content on the top navigation bar 161 ... 162 } 163 } 164 .backgroundColor('#ff08a8f1') 165 .width('100%') 166 } 167 .tabBar ('Home') 168 169 //Other TabContent content: Discover, Recommend, and My 170 ... 171} 172.scrollable(false) 173``` 174 175 176## Fixed navigation bar 177 178When the content categories are relatively fixed and not scalable, for example, the bottom navigation content categories are generally fixed, and the number of categories ranges from 3 to 5, the fixed navigation bar is used. The fixed navigation bar cannot be scrolled or dragged. The content is evenly divided into the width of the tab bar. 179 180 181 Figure 7 Fixed navigation bar 182 183![Fixed Navigation](figures/Fixed Navigation.gif) 184 185 186The barMode attribute of Tabs specifies whether the navigation bar can be scrolled. The default value is Fixed. 187 188 189 190```ts 191Tabs({ barPosition: BarPosition.End }) { 192 // TabContent: home page, discovery, recommendation, and my 193 ... 194} 195.barMode(BarMode.Fixed) 196``` 197 198 199## Scrolling Navigation Bar 200 201The scrolling navigation bar can be used to set the top navigation bar or side navigation bar. If there are many content categories and the screen width cannot accommodate all category tabs, a scrollable navigation bar is required. Users can tap and slide to load hidden tab content. 202 203 204 Figure 8 Scrollable navigation bar 205 206![Scrolling Navigation](figures/Scrolling Navigation.gif) 207 208 209To scroll the navigation bar, you need to set the barMode attribute of the Tabs component. The default value is Fixed, indicating that the navigation bar is fixed. To scroll the navigation bar, set the barMode attribute to Scrollable. 210 211 212 213```ts 214Tabs({ barPosition: BarPosition.Start }) { 215 // TabContent: follow, video, game, digital, technology, sports, movie, humanities, art, nature, and military 216 ... 217} 218.barMode(BarMode.Scrollable) 219``` 220 221 222## Customizing the Navigation Bar 223 224The navigation bar at the bottom is generally used as the main page of the application. For better user experience, text and corresponding semantic icons are combined to indicate the tab content. In this case, you need to customize the style of the navigation tab. 225 226 227 Figure 9 Customizing the navigation bar 228 229![custom-navigation-bar](figures/custom-navigation-bar.png) 230 231 232By default, the system uses underscores (_) to mark active tabs. The customized navigation bar needs to implement the corresponding style to distinguish active tabs from inactive tabs. 233 234 235To customize the navigation bar, you need to use the tabBar parameters and transfer the customized function component style in CustomBuilder mode supported by the tabBar. For example, declare the customized function component of the TabBuilder. The input parameters include the tab text title, corresponding position index, and image resources in the selected and unselected states. The UI display style is determined based on whether the active currentIndex matches the targetIndex corresponding to the tab. 236 237 238 239```ts 240@Builder TabBuilder(title: string, targetIndex: number, selectedImg: Resource, normalImg: Resource) { 241 Column() { 242 Image(this.currentIndex === targetIndex ? selectedImg : normalImg) 243 .size({ width: 25, height: 25 }) 244 Text(title) 245 .fontColor(this.currentIndex === targetIndex ? '#1698CE' : '#6B6B6B') 246 } 247 .width('100%') 248 .height(50) 249 .justifyContent(FlexAlign.Center) 250} 251``` 252 253 254Transfer the customized function component to the tabBar attribute corresponding to TabContent and transfer the corresponding parameters. 255 256 257 258```ts 259TabContent() { 260 Column(){ 261 Text('My Content') 262 } 263 .width('100%') 264 .height('100%') 265 .backgroundColor('#007DFF') 266} 267.tabBar(this.TabBuilder('My', 0, $r('app.media.mine_selected'), $r('app.media.mine_normal'))) 268``` 269 270 271## Switch to a specified tab page. 272 273If the customized navigation bar is not used, the default tabs implement the switching logic. After the customized navigation bar is used, the logic for switching tab pages needs to be manually implemented. That is, when the user taps a corresponding tab, the screen needs to display a corresponding content page. 274 275 276 Figure 10 Using the customized navigation bar to switch to a specified tab page 277 278![Switching to a Specified Tab Page](figures/Switching to a Specified Tab Page.gif) 279 280 281To switch a specified tab page, you need to use the TabsController. The TabsController is the controller of the Tabs component and is used to control the Tabs component to switch tab pages. The changeIndex method of TabsController is used to jump to the TabContent content corresponding to a specified index value. 282 283 284 285```ts 286private tabsController : TabsController = new TabsController() 287@State currentIndex:number = 0; 288 289@Builder TabBuilder(title: string, targetIndex: number) { 290 Column() { 291 Text(title) 292 .fontColor(this.currentIndex === targetIndex ? '#1698CE' : '#6B6B6B') 293 } 294 ... 295 .onClick(() => { 296 this.currentIndex = targetIndex; 297 this.tabsController.changeIndex(this.currentIndex); 298 }) 299} 300``` 301 302 303When using the customized navigation bar, transfer the corresponding \@Builder in the tabBar attribute and transfer the corresponding parameters. 304 305 306 307```ts 308Tabs({ barPosition: BarPosition.End, controller: this.tabsController }) { 309 TabContent(){ 310 ... 311 }.tabBar (this.TabBuilder ('Home', 0)) 312 313 TabContent(){ 314 ... 315 }.tabBar (this.TabBuilder ('Found', 1)) 316 317 TabContent(){ 318 ... 319 }.tabBar (this.TabBuilder ('recommend', 2)) 320 321 TabContent(){ 322 ... 323 } 324 .tabBar (this.TabBuilder (' My',3)) 325} 326``` 327 328 329## Swipe to switch the navigation bar. 330 331If the customized navigation bar is not used, the Tabs implements the switchover association between the TabBar and TabContent by default. However, after the customized navigation bar is used, the TabsController can be used to implement the association between the clicked tab and the page content, but cannot implement the association between the page content and the tab when the page is sliding. That is, when a subscriber swipes on the screen to switch page content, the tab bar needs to be switched to the tab corresponding to the content. 332 333 334 Figure 11 Tab page content is not associated when you slide to switch between tab pages 335 336![Final effect 11] (figures / Final effect 11.gif) 337 338 339In this case, you need to use the onChange event method provided by Tabs to listen to the index change and transfer the active index value to currentIndex to switch the tab content. 340 341 342 343 344```ts 345Tabs({ barPosition: BarPosition.End, controller: this.tabsController }) { 346 TabContent() { 347 ... 348 }.tabBar (this.TabBuilder ('Home', 0)) 349 350 TabContent() { 351 ... 352 }.tabBar (this.TabBuilder ('Found', 1)) 353 354 TabContent() { 355 ... 356 }.tabBar (this.TabBuilder ('Recommend', 2)) 357 358 TabContent() { 359 ... 360 } 361 .tabBar (this.TabBuilder ('My', 3)) 362}.onChange((index) => { 363 this.currentIndex = index 364}) 365``` 366 367 368 Figure 12 Linkage between content and tabs 369 370![Final Effect] (figures / Final Effect.gif) 371 372## Samples 373 374For details about the implementation of tabs, see the following example: 375 376- [Healthy Life] (https://gitee.com/openharmony/codelabs/tree/master/ETSUI/Healthy_life) 377 378- [Common Components and Layout] (https://gitee.com/openharmony/codelabs/tree/master/ETSUI/ArkTSComponents) 379