• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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