1# Navigation
2
3The **Navigation** component is the root view container for navigation. It typically functions as the root container of a page and includes a title bar, content area, and toolbar. The content area switches between the home page content (child components of **Navigation**) and non-home page content (child components of [NavDestination](ts-basic-components-navdestination.md)) through routing.
4
5> **NOTE**
6>
7> - This component is supported since API version 8. Updates will be marked with a superscript to indicate their earliest API version.
8>
9> - Since API version 11, this component supports the safe area attribute by default, with the default attribute value being **expandSafeArea([SafeAreaType.SYSTEM, SafeAreaType.KEYBOARD, SafeAreaType.CUTOUT], [SafeAreaEdge.TOP, 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.
10>
11> - When [NavBar](#navbar12) is nested within a **Navigation** component, the lifecycle of the inner **Navigation** component does not synchronize with the outer **Navigation** component or the lifecycle of a [modal](ts-universal-attributes-modal-transition.md).
12>
13> - If no main title or subtitle is set for **Navigation** and there is no back button, the title bar is not displayed.
14
15
16## Child Components
17
18Supported
19
20Since API version 9, it is recommended that this component be used together with the [NavRouter](ts-basic-components-navrouter.md) component.
21
22Since API version 10, it is recommended that this component be used together with the [NavPathStack](#navpathstack10) component and **navDestination** attribute for page routing.
23
24## APIs
25
26### Navigation
27
28Navigation()
29
30**Atomic service API**: This API can be used in atomic services since API version 11.
31
32**System capability**: SystemCapability.ArkUI.ArkUI.Full
33
34### Navigation<sup>10+</sup>
35
36Navigation(pathInfos: NavPathStack)
37
38Binds a navigation stack to the **Navigation** component.
39
40**Atomic service API**: This API can be used in atomic services since API version 11.
41
42**System capability**: SystemCapability.ArkUI.ArkUI.Full
43
44**Parameters**
45
46| Name      | Type                           | Mandatory  | Description  |
47| --------- | ------------------------------- | ---- | ------ |
48| pathInfos | [NavPathStack](#navpathstack10) | Yes   | Information about the navigation stack.|
49
50## Attributes
51
52In addition to the [universal attributes](ts-universal-attributes-size.md), the following attributes are supported.
53
54### title
55
56title(value: ResourceStr | CustomBuilder | NavigationCommonTitle | NavigationCustomTitle, options?: NavigationTitleOptions)
57
58Sets the page title.
59
60**Atomic service API**: This API can be used in atomic services since API version 11.
61
62**System capability**: SystemCapability.ArkUI.ArkUI.Full
63
64**Parameters**
65
66| Name | Type                                                        | Mandatory| Description                                                        |
67| ------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ |
68| value   | [ResourceStr](ts-types.md#resourcestr)<sup>10+</sup> \| [CustomBuilder](ts-types.md#custombuilder8) \| [NavigationCommonTitle](#navigationcommontitle9)<sup>9+</sup> \| [NavigationCustomTitle](#navigationcustomtitle9)<sup>9+</sup> | Yes  | Page title. When the NavigationCustomTitle type is used to set the height, [titleMode](#titlemode) does not take effect. When the title string is too long: (1) If no subtitle is set, the string is scaled down, wrapped in two lines, and then clipped with an ellipsis (...); (2) If a subtitle is set, the subtitle is scaled down and then clipped with an ellipsis (...).|
69| options | [NavigationTitleOptions](#navigationtitleoptions11)<sup>11+</sup> | No  | Title bar options.                                                  |
70
71### subTitle<sup>(deprecated)</sup>
72
73subTitle(value: string)
74
75Sets the page subtitle.
76
77This API is deprecated since API version 9. You are advised to use [title](#title) instead.
78
79**System capability**: SystemCapability.ArkUI.ArkUI.Full
80
81**Parameters**
82
83| Name| Type  | Mandatory| Description        |
84| ------ | ------ | ---- | ------------ |
85| value  | string | Yes  | Page subtitle.|
86
87### menus
88
89menus(value: Array&lt;NavigationMenuItem&gt; | CustomBuilder)
90
91> **NOTE**
92>
93> The following are not allowed: modify the icon size through the **fontSize** attribute of the **SymbolGlyphModifier** object, change the animation effects through the **effectStrategy** attribute, or change the type of animation effects through the **symbolEffect** attribute.
94
95
96Sets the menu items in the upper right corner of the page. If this attribute is not set, no menu item is displayed. When the value type is Array<[NavigationMenuItem](#navigationmenuitem)&gt;, the menu shows a maximum of three icons in portrait mode and a maximum of five icons in landscape mode, with excess icons (if any) placed under the automatically generated **More** icon.
97
98**Atomic service API**: This API can be used in atomic services since API version 11.
99
100**System capability**: SystemCapability.ArkUI.ArkUI.Full
101
102**Parameters**
103
104| Name| Type                                                        | Mandatory| Description            |
105| ------ | ------------------------------------------------------------ | ---- | ---------------- |
106| value  | Array<[NavigationMenuItem](#navigationmenuitem)&gt; \| [CustomBuilder](ts-types.md#custombuilder8) | Yes  | Menu items in the upper right corner of the page.|
107
108### titleMode
109
110titleMode(value: NavigationTitleMode)
111
112Sets the display mode of the page title bar.
113
114**Atomic service API**: This API can be used in atomic services since API version 11.
115
116**System capability**: SystemCapability.ArkUI.ArkUI.Full
117
118**Parameters**
119
120| Name| Type                                               | Mandatory| Description                                                     |
121| ------ | --------------------------------------------------- | ---- | --------------------------------------------------------- |
122| value  | [NavigationTitleMode](#navigationtitlemode) | Yes  | Display mode of the page title bar.<br>Default value: **NavigationTitleMode.Free**|
123
124### toolBar<sup>(deprecated)</sup>
125
126toolBar(value: object | CustomBuilder)
127
128Sets the content of the toolbar. If this attribute is not set, no toolbar is displayed. Toolbar items are evenly distributed on the bottom toolbar, with text and icons evenly spaced in each content area. If any item contains overlong text and there are fewer than five items, the toolbar will reduce the text size progressively, wrap the text over two lines if necessary, and then clip the text with an ellipsis (...) to fit.
129
130This API is deprecated since API version 10. You are advised to use [toolbarConfiguration](#toolbarconfiguration10) instead.
131
132**System capability**: SystemCapability.ArkUI.ArkUI.Full
133
134**Parameters**
135
136| Name| Type                                                        | Mandatory| Description        |
137| ------ | ------------------------------------------------------------ | ---- | ------------ |
138| value  | object \| [CustomBuilder](ts-types.md#custombuilder8) | Yes  | Content of the toolbar.|
139
140**object**
141
142| Name    | Type           | Mandatory  | Description             |
143| ------ | ------------- | ---- | --------------- |
144| value  | string        | Yes   | Text of the toolbar item.  |
145| icon   | string        | No   | Icon path of the toolbar item.|
146| action | () =&gt; void | No   | Callback invoked when the menu item is selected.  |
147
148### toolbarConfiguration<sup>10+</sup>
149
150toolbarConfiguration(value: Array&lt;ToolbarItem&gt; | CustomBuilder, options?: NavigationToolbarOptions)
151
152> **NOTE**
153>
154> The following are not allowed: modify the icon size through the **fontSize** attribute of the **SymbolGlyphModifier** object, change the animation effects through the **effectStrategy** attribute, or change the type of animation effects through the **symbolEffect** attribute.
155
156
157Sets the content of the toolbar. If this attribute is not set, no toolbar is displayed.
158
159**Widget capability**: Since API version 10, this API is supported in ArkTS widgets.
160
161**Atomic service API**: This API can be used in atomic services since API version 11.
162
163**System capability**: SystemCapability.ArkUI.ArkUI.Full
164
165**Parameters**
166
167| Name | Type                                                        | Mandatory| Description                                                        |
168| ------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ |
169| value   |  Array&lt;[ToolbarItem](#toolbaritem10)&gt;  \| [CustomBuilder](ts-types.md#custombuilder8) | Yes  | Content of the toolbar. When configured with Array&lt;[ToolbarItem](#toolbaritem10)&gt;, the toolbar follows the rules below:<br>Toolbar items are evenly distributed on the bottom toolbar, with text and icons evenly spaced in each content area.<br>- If any item contains overlong text and there are fewer than five items, the toolbar will: 1. Increase the item width to accommodate the text until the toolbar spans the screen width; 2. Reduce the text size progressively; 3. Wrap the text over two lines; 4. Clip the text with an ellipsis (...).<br>In portrait mode, the toolbar shows a maximum of five icons, with any additional icons placed under an automatically generated **More** icon. In landscape mode, the behavior of the toolbar is determined by the display mode: (1) If the display mode is [Split](#navigationmode9), the toolbar follows the same rules as in portrait mode. (2) If the display mode is [Stack](#navigationmode9), the toolbar must be used together with Array&lt;[NavigationMenuItem](#navigationmenuitem)&gt; of the **menus** attribute; in this configuration, the bottom toolbar is automatically hidden, and all items on the toolbar are relocated to the menu in the upper right corner of the screen.<br>When configured with [CustomBuilder](ts-types.md#custombuilder8), the toolbar does not follow the above rules, except for evenly distributing items at the bottom of the toolbar.|
170| options | [NavigationToolbarOptions](#navigationtoolbaroptions11)<sup>11+</sup> | No  | Toolbar options.                                                |
171
172### hideToolBar
173
174hideToolBar(value: boolean)
175
176Specifies whether to hide the toolbar.
177
178**Atomic service API**: This API can be used in atomic services since API version 11.
179
180**System capability**: SystemCapability.ArkUI.ArkUI.Full
181
182**Parameters**
183
184| Name| Type   | Mandatory| Description                                                        |
185| ------ | ------- | ---- | ------------------------------------------------------------ |
186| value  | boolean | Yes  | Whether to hide the toolbar.<br>Default value: **false**<br>**true**: Hide the toolbar.<br>**false**: Show the toolbar.|
187
188### hideToolBar<sup>13+</sup>
189
190hideToolBar(hide: boolean, animated: boolean)
191
192Sets whether to hide the toolbar and whether to animate the visibility change.
193
194**Atomic service API**: This API can be used in atomic services since API version 13.
195
196**System capability**: SystemCapability.ArkUI.ArkUI.Full
197
198**Parameters**
199
200| Name| Type   | Mandatory| Description                                                        |
201| ------ | ------- | ---- | ------------------------------------------------------------ |
202| hide  | boolean | Yes  | Whether to hide the toolbar.<br>Default value: **false**<br>**true**: Hide the toolbar.<br>**false**: Show the toolbar.|
203| animated  | boolean | Yes  | Whether to animate the visibility change.<br>Default value: **false**<br>**true**: Animate the visibility change.<br>**false**: Do not animate the visibility change.|
204
205### hideTitleBar
206
207hideTitleBar(value: boolean)
208
209Specifies whether to hide the title bar.
210
211**Atomic service API**: This API can be used in atomic services since API version 11.
212
213**System capability**: SystemCapability.ArkUI.ArkUI.Full
214
215**Parameters**
216
217| Name| Type   | Mandatory| Description                                                        |
218| ------ | ------- | ---- | ------------------------------------------------------------ |
219| value  | boolean | Yes  | Whether to hide the title bar.<br>Default value: **false**<br>**true**: Hide the title bar.<br>**false**: Show the title bar.|
220
221### hideTitleBar<sup>13+</sup>
222
223hideTitleBar(hide: boolean, animated: boolean)
224
225Sets whether to hide the title bar and whether to animate the visibility change.
226
227**Atomic service API**: This API can be used in atomic services since API version 13.
228
229**System capability**: SystemCapability.ArkUI.ArkUI.Full
230
231**Parameters**
232
233| Name| Type   | Mandatory| Description                                                        |
234| ------ | ------- | ---- | ------------------------------------------------------------ |
235| hide  | boolean | Yes  | Whether to hide the title bar.<br>Default value: **false**<br>**true**: Hide the title bar.<br>**false**: Show the title bar.|
236| animated  | boolean | Yes  | Whether to animate the visibility change.<br>Default value: **false**<br>**true**: Animate the visibility change.<br>**false**: Do not animate the visibility change.|
237
238### hideBackButton
239
240hideBackButton(value: boolean)
241
242Sets whether to hide the back button in the title bar. The back button is available only when [titleMode](#titlemode) is set to **NavigationTitleMode.Mini**.
243
244**Atomic service API**: This API can be used in atomic services since API version 11.
245
246**System capability**: SystemCapability.ArkUI.ArkUI.Full
247
248**Parameters**
249
250| Name| Type   | Mandatory| Description                                                        |
251| ------ | ------- | ---- | ------------------------------------------------------------ |
252| value  | boolean | Yes  | Whether to hide the back button in the title bar.<br>Default value: **false**<br>**true**: Hide the back button.<br>**false**: Show the back button.|
253
254### navBarWidth<sup>9+</sup>
255
256navBarWidth(value: Length)
257
258Sets the width of the navigation bar. This attribute takes effect only when the **Navigation** component is split.
259
260**Atomic service API**: This API can be used in atomic services since API version 11.
261
262**System capability**: SystemCapability.ArkUI.ArkUI.Full
263
264**Parameters**
265
266| Name| Type                        | Mandatory| Description                                     |
267| ------ | ---------------------------- | ---- | ----------------------------------------- |
268| value  | [Length](ts-types.md#length) | Yes  | Width of the navigation bar.<br>Default value: **240**<br>Unit: vp<br>**undefined**: No action is taken, and the navigation bar width remains consistent with the default value.|
269
270### navBarPosition<sup>9+</sup>
271
272navBarPosition(value: NavBarPosition)
273
274Sets the position of the navigation bar. This attribute takes effect only when the **Navigation** component is split.
275
276**Atomic service API**: This API can be used in atomic services since API version 11.
277
278**System capability**: SystemCapability.ArkUI.ArkUI.Full
279
280**Parameters**
281
282| Name| Type                                      | Mandatory| Description                                         |
283| ------ | ------------------------------------------ | ---- | --------------------------------------------- |
284| value  | [NavBarPosition](#navbarposition9) | Yes  | Position of the navigation bar.<br>Default value: **NavBarPosition.Start**|
285
286### mode<sup>9+</sup>
287
288mode(value: NavigationMode)
289
290Sets the display mode of the navigation bar. Available options are **Stack**, **Split**, and **Auto**.
291
292**Atomic service API**: This API can be used in atomic services since API version 11.
293
294**System capability**: SystemCapability.ArkUI.ArkUI.Full
295
296**Parameters**
297
298| Name| Type                                      | Mandatory| Description                                                        |
299| ------ | ------------------------------------------ | ---- | ------------------------------------------------------------ |
300| value  | [NavigationMode](#navigationmode9) | Yes  | Display mode of the navigation bar.<br>Default value: **NavigationMode.Auto**<br>At the default settings, the component adapts to a single column or two columns based on the component width.|
301
302### backButtonIcon<sup>9+</sup>
303
304backButtonIcon(value: string | PixelMap | Resource | SymbolGlyphModifier)
305
306> **NOTE**
307>
308> The following are not allowed: modify the icon size through the **fontSize** attribute of the **SymbolGlyphModifier** object, change the animation effects through the **effectStrategy** attribute, or change the type of animation effects through the **symbolEffect** attribute.
309
310
311Sets the icon of the back button in the title bar.
312
313**Atomic service API**: This API can be used in atomic services since API version 11.
314
315**System capability**: SystemCapability.ArkUI.ArkUI.Full
316
317**Parameters**
318
319| Name| Type                                                        | Mandatory| Description                |
320| ------ | ------------------------------------------------------------ | ---- | -------------------- |
321| value  | string \| [PixelMap](../../apis-image-kit/js-apis-image.md#pixelmap7) \| [Resource](ts-types.md#resource) \| [SymbolGlyphModifier<sup>12+</sup>](ts-universal-attributes-attribute-modifier.md)    | Yes  | Icon of the back button in the title bar.|
322
323### hideNavBar<sup>9+</sup>
324
325hideNavBar(value: boolean)
326
327Specifies whether to hide the navigation bar. If this parameter is set to **true**, the navigation bar, including the title bar, content area, and toolbar, is hidden. In this case, if the navigation destination page is in the navigation stack, it is moved to the top of the stack and displayed. Otherwise, a blank page is displayed.
328
329From API version 9 to API version 10, this attribute takes effect only in dual-column mode. Since API version 11, this attribute takes effect in single-column, dual-column, and auto modes.
330
331**Atomic service API**: This API can be used in atomic services since API version 11.
332
333**System capability**: SystemCapability.ArkUI.ArkUI.Full
334
335**Parameters**
336
337| Name| Type   | Mandatory| Description                              |
338| ------ | ------- | ---- | ---------------------------------- |
339| value  | boolean | Yes  | Whether to hide the navigation bar.<br>Default value: **false**|
340
341### navDestination<sup>10+</sup>
342
343navDestination(builder: (name: string, param: unknown) => void)
344
345Builder for a **NavDestination** component. The **builder** function is used, with the **name** and **param** parameters passed in. The **builder** can have only one root node. In the builder, a layer of custom components can be included outside the **NavDestination** component. However, no attributes or events can be set for the custom components. Otherwise, only blank components are displayed.
346
347**Atomic service API**: This API can be used in atomic services since API version 11.
348
349**System capability**: SystemCapability.ArkUI.ArkUI.Full
350
351**Parameters**
352
353| Name | Type                                  | Mandatory| Description                    |
354| ------- | -------------------------------------- | ---- | ------------------------ |
355| builder | (name: string, param: unknown) => void | Yes  | Builder for a **NavDestination** component. **name**: name of the navigation destination page. **param**: detailed parameters of the navigation destination page.|
356
357### navBarWidthRange<sup>10+</sup>
358
359navBarWidthRange(value: [Dimension, Dimension])
360
361Sets the minimum and maximum widths of the navigation bar (effective in dual-column mode).
362
363For details about the priority rules, see **NOTE** below.
364
365**Atomic service API**: This API can be used in atomic services since API version 11.
366
367**System capability**: SystemCapability.ArkUI.ArkUI.Full
368
369**Parameters**
370
371| Name | Type                                                        | Mandatory| Description                                                        |
372| ------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ |
373| value | [[Dimension](ts-types.md#dimension10), [Dimension](ts-types.md#dimension10)] | Yes  | Minimum and maximum widths of the navigation bar.<br>Default value: 240 for the minimum value; 40% of the component width (not greater than 432) for the maximum value; if either of the widths is not set, the default value is used for that width.<br>Unit: vp|
374
375### minContentWidth<sup>10+</sup>
376
377minContentWidth(value: Dimension)
378
379Sets the minimum width of the navigation bar content area (effective in dual-column mode).
380
381For details about the priority rules, see **NOTE** below.
382
383**Atomic service API**: This API can be used in atomic services since API version 11.
384
385**System capability**: SystemCapability.ArkUI.ArkUI.Full
386
387**Parameters**
388
389| Name | Type                                | Mandatory| Description                                                        |
390| ------- | ------------------------------------ | ---- | ------------------------------------------------------------ |
391| value | [Dimension](ts-types.md#dimension10) | Yes  | Minimum width of the navigation bar content area.<br>Default value: **360**<br>Unit: vp<br>**undefined**: No action is taken, and the minimum width of the navigation bar remains consistent with the default value.<br>Breakpoint calculation in Auto mode: default 600 vp = minNavBarWidth (240 vp) + minContentWidth (360 vp)|
392
393>  **NOTE**
394>
395>  1. If only **navBarWidth** is set, no divider in the **Navigation** component can be dragged.
396>
397>  2. **navBarWidthRange** specifies the range within which the divider can be dragged. If it is not set, the default value is used. The dragging of the divider is subject to both **navBarWidthRange** and **minContentWidth**.
398>
399>  3. If the size of the **Navigation** component decreases, it carries out the following steps in sequence:<br>a. Scale down the content area. If **minContentWidth** is not set, the content area can be scaled down to 0. Otherwise, the content area can be scaled down to as small as the value specified by **minContentWidth**.b. Scale down the navigation bar until its width reaches the value defined by **navBarRange**.c. Clip the displayed content.
400
401### ignoreLayoutSafeArea<sup>12+</sup>
402
403ignoreLayoutSafeArea(types?: Array&lt;LayoutSafeAreaType&gt;, edges?: Array&lt;LayoutSafeAreaEdge&gt;)
404
405Ignores the layout safe area by allowing the component to extend into the non-safe areas of the screen.
406
407**Atomic service API**: This API can be used in atomic services since API version 12.
408
409**System capability**: SystemCapability.ArkUI.ArkUI.Full
410
411**Parameters**
412
413| Name| Type                                              | Mandatory| Description                                                        |
414| ------ | -------------------------------------------------- | ---- | ------------------------------------------------------------ |
415| types  | Array <[LayoutSafeAreaType](ts-types.md#layoutsafeareatype12)> | No  | Types of non-safe areas to extend into.<br>Default value:<br>[LayoutSafeAreaType.SYSTEM] |
416| edges  | Array <[LayoutSafeAreaEdge](ts-types.md#layoutsafeareaedge12)> | No  | Edges for expanding the safe area.<br> Default value:<br>[LayoutSafeAreaEdge.TOP, LayoutSafeAreaEdge.BOTTOM]|
417
418>  **NOTE**
419>
420>  After **LayoutSafeArea** is set:
421>  When **LayoutSafeAreaType.SYSTEM** is set, the component can extend into the non-safe area if its boundaries overlap with it. For example, if the device's status bar is 100 high, the component can extend into the non-safe area only when there is an absolute vertical offset between 0 and 100.
422>
423>  If the component extends into the non-safe area, events triggered within that area (such as click events) might be intercepted by the system. This allows the system to prioritize responses to system components such as the status bar.
424
425### systemBarStyle<sup>12+</sup>
426
427systemBarStyle(style: Optional&lt;SystemBarStyle&gt;)
428
429Sets the style of the system status bar when the home page of the **Navigation** component is displayed.
430
431**Atomic service API**: This API can be used in atomic services since API version 12.
432
433**System capability**: SystemCapability.ArkUI.ArkUI.Full
434
435**Parameters**
436
437| Name| Type        | Mandatory| Description              |
438| ------ | -------------- | ---- | ------------------ |
439| style  | Optional&lt;[SystemBarStyle](#systembarstyle12)&gt; | Yes  | Style of the system status bar.|
440
441>  **Instructions**
442>
443> 1. Avoid using the **systemBarStyle** attribute in conjunction with the status bar style APIs in the **Window** module, such as [setWindowSystemBarProperties](../js-apis-window.md#setwindowsystembarproperties9).
444> 2. When you first set the **systemBarStyle** attribute for a **Navigation** or **NavDestination** component, the current status bar style is saved for potential future restoration.
445> 3. The status bar style is determined by the home page of the **Navigation** component (if there are no **NavDestination** pages on the navigation stack) or the top **NavDestination** page on the navigation stack.
446> 4. If the home page or any top **NavDestination** page has a valid **systemBarStyle** set, that style will be used. If no style is set, and there is a previously saved style available, the saved style will be used. If no style has been set or saved, no changes will be made.
447> 5. In [Split](#navigationmode9) mode, if there is no **NavDestination** in the content area, the settings of the **Navigation** home page will apply. Otherwise, the settings of the top **NavDestination** page on the navigation stack will apply.
448> 6. The **systemBarStyle** attribute is effective only for the main page of the main window.
449> 7. The set style will only take effect if the **Navigation** component spans the entire page. If it does not, and there is a previously saved style available, the saved style will be used instead.
450> 8. When different styles are set for pages, the new style takes effect at the start of the page transition.
451> 9. The status bar style set by **Navigation** or **NavDestination** does not apply in non-fullscreen windows.
452
453### recoverable<sup>14+</sup>
454
455recoverable(recoverable: Optional&lt;boolean&gt;)
456
457Sets whether the **Navigation** component is recoverable. If set to recoverable, when the application process exits unexpectedly and restarts, the **Navigation** component will be automatically recreated, and the navigation stack will be restored to the state at the time of the unexpected exit.
458
459**Atomic service API**: This API can be used in atomic services since API version 14.
460
461**System capability**: SystemCapability.ArkUI.ArkUI.Full
462
463**Parameters**
464
465| Name| Type        | Mandatory| Description              |
466| ------ | -------------- | ---- | ------------------ |
467| recoverable  | Optional&lt;boolean&gt; | Yes  | Whether the **Navigation** component is recoverable. By default, it is not recoverable.|
468
469>  **Instructions**
470>
471> 1. For this API to work properly, you must first set the [id](ts-universal-attributes-component-id.md#id) attribute of the **Navigation** component.
472> 2. This API must be used together with the [recoverable](./ts-basic-components-navdestination.md#recoverable14) API of **NavDestination**.
473> 3. Non-serializable information, such as non-serializable parameters and custom **onPop**, is discarded and cannot be restored during the recovery process.
474
475### enableDragBar<sup>14+</sup>
476
477enableDragBar(isEnabled: Optional&lt;boolean&gt;)
478
479Sets whether to display a drag bar in split-column scenarios.
480
481**Atomic service API**: This API can be used in atomic services since API version 14.
482
483**System capability**: SystemCapability.ArkUI.ArkUI.Full
484
485**Parameters**
486
487| Name| Type        | Mandatory| Description              |
488| ------ | -------------- | ---- | ------------------ |
489| enableDragBar  | Optional&lt;boolean&gt; | Yes  | Whether to enable the drag bar. By default, there is no drag bar.|
490
491## Events
492
493### onTitleModeChange
494
495onTitleModeChange(callback: (titleMode: NavigationTitleMode) =&gt; void)
496
497Triggered when [titleMode](#titlemode) is set to **NavigationTitleMode.Free** and the title bar mode changes as content scrolls.
498
499**Atomic service API**: This API can be used in atomic services since API version 11.
500
501**System capability**: SystemCapability.ArkUI.ArkUI.Full
502
503**Parameters**
504
505| Name   | Type                                               | Mandatory| Description      |
506| --------- | --------------------------------------------------- | ---- | ---------- |
507| titleMode | [NavigationTitleMode](#navigationtitlemode) | Yes  | Title mode.|
508
509### onNavBarStateChange<sup>9+</sup>
510
511onNavBarStateChange(callback: (isVisible: boolean) =&gt; void)
512
513Triggered when the navigation bar visibility status changes.
514
515**Atomic service API**: This API can be used in atomic services since API version 11.
516
517**System capability**: SystemCapability.ArkUI.ArkUI.Full
518
519**Parameters**
520
521| Name   | Type   | Mandatory| Description                                          |
522| --------- | ------- | ---- | ---------------------------------------------- |
523| isVisible | boolean | Yes  | Whether the navigation bar is visible. The value **true** means that the navigation bar is visible, and **false** means the opposite.|
524
525### onNavigationModeChange<sup>11+</sup>
526
527onNavigationModeChange(callback: (mode: NavigationMode) =&gt; void)
528
529Triggered when the **Navigation** component is displayed for the first time or its display mode switches between single-column and dual-column.
530
531**Atomic service API**: This API can be used in atomic services since API version 11.
532
533**System capability**: SystemCapability.ArkUI.ArkUI.Full
534
535**Parameters**
536
537| Name   | Type   | Mandatory| Description                                          |
538| --------- | ------- | ---- | ---------------------------------------------- |
539| mode | [NavigationMode](#navigationmode9) | Yes  | **NavigationMode.Split**: The component is displayed in two columns.<br>**NavigationMode.Stack**: The component is displayed in a single column.|
540
541### customNavContentTransition<sup>11+</sup>
542
543customNavContentTransition(delegate:(from: NavContentInfo, to: NavContentInfo, operation: NavigationOperation) => NavigationAnimatedTransition | undefined)
544
545Callback of the custom transition animation.
546
547**Atomic service API**: This API can be used in atomic services since API version 12.
548
549**System capability**: SystemCapability.ArkUI.ArkUI.Full
550
551**Parameters**
552
553| Name   | Type                                                 | Mandatory| Description                   |
554| --------- | ----------------------------------------------------- | ---- | ----------------------- |
555| from      | [NavContentInfo](#navcontentinfo11)                   | Yes  | Destination page to exit.|
556| to        | [NavContentInfo](#navcontentinfo11)                   | Yes  | Destination page to enter.|
557| operation | [NavigationOperation](#navigationoperation11) | Yes  | Transition type.             |
558
559**Return value**
560
561| Type                                                        | Description                                                        |
562| ------------------------------------------------------------ | ------------------------------------------------------------ |
563| [NavigationAnimatedTransition](#navigationanimatedtransition11) \| undefined | Custom transition animation agreement.<br>**undefined**: The default transition effect is executed.|
564
565## NavPathStack<sup>10+</sup>
566
567Implements a navigation stack, which allows for inheritance since API version 12. You can add new properties and methods in derived classes, or you can override the methods of the base **NavPathStack** class. Objects of the derived class can be used in place of objects of the base **NavPathStack** class. For details, see [Example 10](#example-10-defining-a-derived-class-of-navpathstack).
568
569> **NOTE**
570>
571> 1. When multiple page stack operations are triggered in succession, the intermediate states are bypassed, and only the final result of the stack operations is rendered.<br>
572> For example, if a Page1 is popped and then immediately pushed back, the system considers that the states before and after these operations are identical, leading to no actual change in the stack. To ensure that a new instance of Page1 is pushed onto the stack despite the consecutive operations, use the **NEW_INSTANCE** mode.
573>
574> 2. Avoid relying on lifecycle event listeners as a means to manage the navigation stack.
575
576### constructor
577
578constructor()
579
580**Atomic service API**: This API can be used in atomic services since API version 11.
581
582**System capability**: SystemCapability.ArkUI.ArkUI.Full
583
584### pushPath<sup>10+</sup>
585
586pushPath(info: NavPathInfo, animated?: boolean): void
587
588Pushes the navigation destination page specified by **info** onto the navigation stack.
589
590**Atomic service API**: This API can be used in atomic services since API version 11.
591
592**System capability**: SystemCapability.ArkUI.ArkUI.Full
593
594**Parameters**
595
596| Name  | Type                           | Mandatory  | Description                  |
597| ---- | ----------------------------- | ---- | -------------------- |
598| info | [NavPathInfo](#navpathinfo10) | Yes   | Information about the navigation destination page.|
599| animated<sup>11+</sup> | boolean | No   | Whether to support transition animation.<br>Default value: **true**|
600
601### pushPath<sup>12+</sup>
602
603pushPath(info: NavPathInfo, options?: NavigationOptions): void
604
605Pushes the navigation destination page specified by **info** onto the navigation stack. Depending on the [LaunchMode](#launchmode12) specified in the **options** parameter, different behaviors will be triggered.
606
607**Atomic service API**: This API can be used in atomic services since API version 12.
608
609**System capability**: SystemCapability.ArkUI.ArkUI.Full
610
611**Parameters**
612
613| Name  | Type                           | Mandatory  | Description                  |
614| ---- | ----------------------------- | ---- | -------------------- |
615| info | [NavPathInfo](#navpathinfo10) | Yes   | Information about the navigation destination page.|
616| options | [NavigationOptions](#navigationoptions12) | No   | Navigation options.|
617
618### pushPathByName<sup>10+</sup>
619
620pushPathByName(name: string, param: unknown, animated?: boolean): void
621
622Pushes the navigation destination page specified by **name**, with the data specified by **param**, to the navigation stack.
623
624**Atomic service API**: This API can be used in atomic services since API version 11.
625
626**System capability**: SystemCapability.ArkUI.ArkUI.Full
627
628**Parameters**
629
630| Name   | Type     | Mandatory  | Description                   |
631| ----- | ------- | ---- | --------------------- |
632| name  | string  | Yes   | Name of the navigation destination page.  |
633| param | unknown | Yes   | Detailed parameters of the navigation destination page.|
634| animated<sup>11+</sup> | boolean | No   | Whether to support transition animation.<br>Default value: **true**|
635
636### pushPathByName<sup>11+</sup>
637
638pushPathByName(name: string, param: Object, onPop: Callback\<PopInfo>, animated?: boolean): void
639
640Pushes the navigation destination page specified by **name**, with the data specified by **param**, to the navigation stack. This API uses the **onPop** callback to receive the result returned when the page is popped out of the stack.
641
642**Atomic service API**: This API can be used in atomic services since API version 12.
643
644**System capability**: SystemCapability.ArkUI.ArkUI.Full
645
646**Parameters**
647
648| Name| Type| Mandatory| Description|
649|------|------|------|------|
650| name  | string  | Yes   | Name of the navigation destination page.  |
651| param | Object | Yes   | Detailed parameters of the navigation destination page.|
652| onPop | Callback\<[PopInfo](#popinfo11)> | Yes| Callback used to receive the result. It is invoked only after the **result** parameter is set in **pop**.|
653| animated | boolean | No   | Whether to support transition animation.<br>Default value: **true**|
654
655### pushDestination<sup>11+</sup>
656
657pushDestination(info: NavPathInfo, animated?: boolean): Promise&lt;void&gt;
658
659Pushes the navigation destination page specified by **info** onto the navigation stack. This API uses a promise to return the result.
660
661**Atomic service API**: This API can be used in atomic services since API version 12.
662
663**System capability**: SystemCapability.ArkUI.ArkUI.Full
664
665**Parameters**
666
667| Name  | Type                           | Mandatory  | Description                  |
668| ---- | ----------------------------- | ---- | -------------------- |
669| info | [NavPathInfo](#navpathinfo10) | Yes   | Information about the navigation destination page.|
670| animated | boolean | No   | Whether to support transition animation.<br>Default value: **true**|
671
672**Return value**
673
674| Type               | Description       |
675| ------------------- | --------- |
676| Promise&lt;void&gt; | Promise used to return the result.|
677
678**Error codes**
679
680For details about the error codes, see [Universal Error Codes](../../errorcode-universal.md) and [Router Error Codes](../errorcode-router.md).
681
682| ID  | Error Message|
683| --------- | ------- |
684| 401      | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed.   |
685| 100001    | Internal error.|
686| 100005    | Builder function not registered. |
687| 100006    | NavDestination not found.|
688
689### pushDestination<sup>12+</sup>
690
691pushDestination(info: NavPathInfo, options?: NavigationOptions): Promise&lt;void&gt;
692
693Pushes the navigation destination page specified by **info** onto the navigation stack. This API uses a promise to return the result. Depending on the [LaunchMode](#launchmode12) specified in the **options** parameter, different behaviors will be triggered.
694
695**Atomic service API**: This API can be used in atomic services since API version 12.
696
697**System capability**: SystemCapability.ArkUI.ArkUI.Full
698
699**Parameters**
700
701| Name  | Type                           | Mandatory  | Description                  |
702| ---- | ----------------------------- | ---- | -------------------- |
703| info | [NavPathInfo](#navpathinfo10) | Yes   | Information about the navigation destination page.|
704| options | [NavigationOptions](#navigationoptions12) | No   | Navigation options.|
705
706**Return value**
707
708| Type               | Description       |
709| ------------------- | --------- |
710| Promise&lt;void&gt; | Promise used to return the result.|
711
712**Error codes**
713
714For details about the error codes, see [Universal Error Codes](../../errorcode-universal.md) and [Router Error Codes](../errorcode-router.md).
715
716| ID  | Error Message|
717| --------- | ------- |
718| 401      | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed.   |
719| 100001    | Internal error.|
720| 100005    | Builder function not registered. |
721| 100006    | NavDestination not found.|
722
723### pushDestinationByName<sup>11+</sup>
724
725pushDestinationByName(name: string, param: Object, animated?: boolean): Promise&lt;void&gt;
726
727Pushes the navigation destination page specified by **name**, with the data specified by **param**, to the navigation stack. This API uses a promise to return the result.
728
729**Atomic service API**: This API can be used in atomic services since API version 12.
730
731**System capability**: SystemCapability.ArkUI.ArkUI.Full
732
733**Parameters**
734
735| Name   | Type     | Mandatory  | Description                   |
736| ----- | ------- | ---- | --------------------- |
737| name  | string  | Yes   | Name of the navigation destination page.  |
738| param | Object | Yes   | Detailed parameters of the navigation destination page.|
739| animated | boolean | No   | Whether to support transition animation.<br>Default value: **true**|
740
741**Return value**
742
743| Type               | Description       |
744| ------------------- | --------- |
745| Promise&lt;void&gt; | Promise used to return the result.|
746
747**Error codes**
748
749For details about the error codes, see [Universal Error Codes](../../errorcode-universal.md) and [Router Error Codes](../errorcode-router.md).
750
751| ID  | Error Message|
752| --------- | ------- |
753| 401      | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed.   |
754| 100001    | Internal error.|
755| 100005    | Builder function not registered. |
756| 100006    | NavDestination not found.|
757
758### pushDestinationByName<sup>11+</sup>
759
760pushDestinationByName(name: string, param: Object, onPop: Callback\<PopInfo>, animated?: boolean): Promise&lt;void&gt;
761
762Pushes the navigation destination page specified by **name**, with the data specified by **param**, to the navigation stack. This API uses the **onPop** callback to handle the result returned when the page is popped out of the stack. It uses a promise to return the result.
763
764**Atomic service API**: This API can be used in atomic services since API version 12.
765
766**System capability**: SystemCapability.ArkUI.ArkUI.Full
767
768**Parameters**
769
770| Name   | Type     | Mandatory  | Description                   |
771| ----- | ------- | ---- | --------------------- |
772| name  | string  | Yes   | Name of the navigation destination page.  |
773| param | Object | Yes   | Detailed parameters of the navigation destination page.|
774| onPop | Callback\<[PopInfo](#popinfo11)> | Yes   | Callback used to handle the result returned when the page is popped out of the stack. It is invoked only after the **result** parameter is set in **pop**.|
775| animated | boolean | No   | Whether to support transition animation.<br>Default value: **true**|
776
777**Return value**
778
779| Type               | Description       |
780| ------------------- | --------- |
781| Promise&lt;void&gt; | Promise used to return the result.|
782
783**Error codes**
784
785For details about the error codes, see [Universal Error Codes](../../errorcode-universal.md) and [Router Error Codes](../errorcode-router.md).
786
787| ID  | Error Message|
788| --------- | ------- |
789| 401      | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed.   |
790| 100001    | Internal error.|
791| 100005    | Builder function not registered. |
792| 100006    | NavDestination not found.|
793
794### replacePath<sup>11+</sup>
795
796replacePath(info: NavPathInfo, animated?: boolean): void
797
798Replaces the top of the navigation stack with the page specified by **info**.
799
800**Atomic service API**: This API can be used in atomic services since API version 12.
801
802**System capability**: SystemCapability.ArkUI.ArkUI.Full
803
804**Parameters**
805
806| Name  | Type                           | Mandatory  | Description                  |
807| ---- | ----------------------------- | ---- | -------------------- |
808| info | [NavPathInfo](#navpathinfo10) | Yes   | Parameters of the page to replace the top of the navigation stack.|
809| animated<sup>11+</sup> | boolean | No   | Whether to support transition animation.<br>Default value: **true**|
810
811### replacePath<sup>12+</sup>
812
813replacePath(info: NavPathInfo, options?: NavigationOptions): void
814
815Replaces the top page on the navigation stack. Depending on the [LaunchMode](#launchmode12) specified in the **options** parameter, different behaviors will be triggered.
816
817**Atomic service API**: This API can be used in atomic services since API version 12.
818
819**System capability**: SystemCapability.ArkUI.ArkUI.Full
820
821**Parameters**
822
823| Name  | Type                           | Mandatory  | Description                  |
824| ---- | ----------------------------- | ---- | -------------------- |
825| info | [NavPathInfo](#navpathinfo10) | Yes   | Parameters for the new top page of the navigation stack.|
826| options | [NavigationOptions](#navigationoptions12) | No   | Navigation options.|
827
828### replacePathByName<sup>11+</sup>
829
830replacePathByName(name: string, param: Object, animated?: boolean): void
831
832Replaces the top of the navigation stack with the page specified by **name**.
833
834**Atomic service API**: This API can be used in atomic services since API version 12.
835
836**System capability**: SystemCapability.ArkUI.ArkUI.Full
837
838**Parameters**
839
840| Name   | Type     | Mandatory  | Description                   |
841| ----- | ------- | ---- | --------------------- |
842| name  | string  | Yes   | Name of the navigation destination page.  |
843| param | Object | Yes   | Detailed parameters of the navigation destination page.|
844| animated<sup>11+</sup> | boolean | No   | Whether to support transition animation.<br>Default value: **true**|
845
846### removeByIndexes<sup>11+</sup>
847
848removeByIndexes(indexes: Array<number\>): number
849
850Removes the navigation destination pages specified by **indexes** from the navigation stack.
851
852**Atomic service API**: This API can be used in atomic services since API version 12.
853
854**System capability**: SystemCapability.ArkUI.ArkUI.Full
855
856**Parameters**
857
858| Name   | Type     | Mandatory  | Description                   |
859| ----- | ------- | ---- | --------------------- |
860| indexes  | Array<number\>  | Yes   | Array of indexes of the navigation destination pages to remove.  |
861
862**Return value**
863
864| Type         | Description                      |
865| ----------- | ------------------------ |
866| number | Number of the navigation destination pages removed.|
867
868### removeByName<sup>11+</sup>
869
870removeByName(name: string): number
871
872Removes the navigation destination page specified by **name** from the navigation stack.
873
874**Atomic service API**: This API can be used in atomic services since API version 12.
875
876**System capability**: SystemCapability.ArkUI.ArkUI.Full
877
878**Parameters**
879
880| Name   | Type     | Mandatory  | Description                   |
881| ----- | ------- | ---- | --------------------- |
882| name  | string  | Yes   | Name of the navigation destination page to remove.  |
883
884**Return value**
885
886| Type         | Description                      |
887| ----------- | ------------------------ |
888| number | Number of the navigation destination pages removed.|
889
890### removeByNavDestinationId<sup>12+</sup>
891
892removeByNavDestinationId(navDestinationId: string): boolean
893
894Removes the navigation destination page specified by **navDestinationId** from the navigation stack. **navDestinationId** can be obtained from the [onReady](ts-basic-components-navdestination.md#onready11) callback of **NavDestination** or from [NavDestinationInfo](../js-apis-arkui-observer.md#navdestinationinfo).
895
896**Atomic service API**: This API can be used in atomic services since API version 12.
897
898**System capability**: SystemCapability.ArkUI.ArkUI.Full
899
900**Parameters**
901
902| Name   | Type     | Mandatory  | Description                   |
903| ----- | ------- | ---- | --------------------- |
904| navDestinationId  | string  | Yes   | Unique ID of the navigation destination page to remove.  |
905
906**Return value**
907
908| Type         | Description                      |
909| ----------- | ------------------------ |
910| boolean | Whether the page is removed successfully. The value **true** indicates that the page is removed successfully.|
911
912### pop<sup>10+</sup>
913
914pop(animated?: boolean): NavPathInfo | undefined
915
916Pops the top element out of the navigation stack.
917
918**Atomic service API**: This API can be used in atomic services since API version 11.
919
920**System capability**: SystemCapability.ArkUI.ArkUI.Full
921
922**Parameters**
923
924| Name  | Type                           | Mandatory  | Description                  |
925| ---- | ----------------------------- | ---- | -------------------- |
926| animated<sup>11+</sup> | boolean | No   | Whether to support transition animation.<br>Default value: **true**|
927
928**Return value**
929
930| Type         | Description                      |
931| ----------- | ------------------------ |
932| [NavPathInfo](#navpathinfo10) | Returns the information about the navigation destination page at the top of the stack.|
933| undefined   | Returns **undefined** if the navigation stack is empty.     |
934
935### pop<sup>11+</sup>
936
937pop(result: Object, animated?: boolean): NavPathInfo | undefined
938
939Pops the top element out of the navigation stack and invokes the **onPop** callback to pass the page processing result.
940
941**Atomic service API**: This API can be used in atomic services since API version 12.
942
943**System capability**: SystemCapability.ArkUI.ArkUI.Full
944
945**Parameters**
946
947| Name  | Type                           | Mandatory  | Description                  |
948| ---- | ----------------------------- | ---- | -------------------- |
949| result | Object | Yes| Custom processing result on the page. The boolean type is not supported.|
950| animated | boolean | No   | Whether to support transition animation.<br>Default value: **true**|
951
952**Return value**
953
954| Type         | Description                      |
955| ----------- | ------------------------ |
956| [NavPathInfo](#navpathinfo10) | Returns the information about the navigation destination page at the top of the stack.|
957| undefined   | Returns **undefined** if the navigation stack is empty.     |
958
959### popToName<sup>10+</sup>
960
961popToName(name: string, animated?: boolean): number
962
963Pops pages until the first navigation destination page that matches **name** from the bottom of the navigation stack is at the top of the stack.
964
965**Atomic service API**: This API can be used in atomic services since API version 11.
966
967**System capability**: SystemCapability.ArkUI.ArkUI.Full
968
969**Parameters**
970
971| Name  | Type    | Mandatory  | Description                 |
972| ---- | ------ | ---- | ------------------- |
973| name | string | Yes   | Name of the navigation destination page.|
974| animated<sup>11+</sup> | boolean | No   | Whether to support transition animation.<br>Default value: **true**|
975
976**Return value**
977
978| Type    | Description                                      |
979| ------ | ---------------------------------------- |
980| number | Returns the index of the first navigation destination page that matches **name** from the bottom of the navigation stack; returns **-1** if such a page does not exist.|
981
982### popToName<sup>11+</sup>
983
984popToName(name: string, result: Object, animated?: boolean): number
985
986Pops pages until the first navigation destination page that matches **name** from the bottom of the navigation stack is at the top of the stack. This API uses the **onPop** callback to pass in the page processing result.
987
988**Atomic service API**: This API can be used in atomic services since API version 12.
989
990**System capability**: SystemCapability.ArkUI.ArkUI.Full
991
992**Parameters**
993
994| Name  | Type    | Mandatory  | Description                 |
995| ---- | ------ | ---- | ------------------- |
996| name | string | Yes   | Name of the navigation destination page.|
997| result | Object | Yes| Custom processing result on the page. The boolean type is not supported.|
998| animated | boolean | No   | Whether to support transition animation.<br>Default value: **true**|
999
1000**Return value**
1001
1002| Type    | Description                                      |
1003| ------ | ---------------------------------------- |
1004| number | Returns the index of the first navigation destination page that matches **name** from the bottom of the navigation stack; returns **-1** if such a page does not exist.|
1005
1006### popToIndex<sup>10+</sup>
1007
1008popToIndex(index: number, animated?: boolean): void
1009
1010Returns the navigation stack to the page specified by **index**.
1011
1012**Atomic service API**: This API can be used in atomic services since API version 11.
1013
1014**System capability**: SystemCapability.ArkUI.ArkUI.Full
1015
1016**Parameters**
1017
1018| Name   | Type    | Mandatory  | Description                    |
1019| ----- | ------ | ---- | ---------------------- |
1020| index | number | Yes   | Index of the navigation destination page.|
1021| animated<sup>11+</sup> | boolean | No   | Whether to support transition animation.<br>Default value: **true**|
1022
1023### popToIndex<sup>11+</sup>
1024
1025popToIndex(index: number, result: Object, animated?: boolean): void
1026
1027Returns the navigation stack to the page specified by **index** and invokes the **onPop** callback to pass the page processing result.
1028
1029**Atomic service API**: This API can be used in atomic services since API version 11.
1030
1031**System capability**: SystemCapability.ArkUI.ArkUI.Full
1032
1033**Parameters**
1034
1035| Name   | Type    | Mandatory  | Description                    |
1036| ----- | ------ | ---- | ---------------------- |
1037| index | number | Yes   | Index of the navigation destination page.|
1038| result | Object | Yes| Custom processing result on the page. The boolean type is not supported.|
1039| animated | boolean | No   | Whether to support transition animation.<br>Default value: **true**|
1040
1041### moveToTop<sup>10+</sup>
1042
1043moveToTop(name: string, animated?: boolean): number
1044
1045Moves the first navigation destination page that matches **name** from the bottom of the navigation stack to the top of the stack.
1046
1047**Atomic service API**: This API can be used in atomic services since API version 11.
1048
1049**System capability**: SystemCapability.ArkUI.ArkUI.Full
1050
1051**Parameters**
1052
1053| Name  | Type    | Mandatory  | Description                 |
1054| ---- | ------ | ---- | ------------------- |
1055| name | string | Yes   | Name of the navigation destination page.|
1056| animated<sup>11+</sup> | boolean | No   | Whether to support transition animation.<br>Default value: **true**|
1057
1058**Return value**
1059
1060| Type    | Description                                      |
1061| ------ | ---------------------------------------- |
1062| number | Returns the index of the first navigation destination page that matches **name** from the bottom of the navigation stack; returns **-1** if such a page does not exist.|
1063
1064### moveIndexToTop<sup>10+</sup>
1065
1066moveIndexToTop(index: number, animated?: boolean): void
1067
1068Moves to the top of the navigation stack the navigation destination page specified by **index**.
1069
1070**Atomic service API**: This API can be used in atomic services since API version 11.
1071
1072**System capability**: SystemCapability.ArkUI.ArkUI.Full
1073
1074**Parameters**
1075
1076| Name   | Type    | Mandatory  | Description                    |
1077| ----- | ------ | ---- | ---------------------- |
1078| index | number | Yes   | Index of the navigation destination page.|
1079| animated<sup>11+</sup> | boolean | No   | Whether to support transition animation.<br>Default value: **true**|
1080
1081### clear<sup>10+</sup>
1082
1083clear(animated?: boolean): void
1084
1085Clears the navigation stack.
1086
1087**Atomic service API**: This API can be used in atomic services since API version 11.
1088
1089**System capability**: SystemCapability.ArkUI.ArkUI.Full
1090
1091**Parameters**
1092
1093| Name   | Type    | Mandatory  | Description                    |
1094| ----- | ------ | ---- | ---------------------- |
1095| animated<sup>11+</sup> | boolean | No   | Whether to support transition animation.<br>Default value: **true**|
1096
1097### getAllPathName<sup>10+</sup>
1098
1099getAllPathName(): Array<string\>
1100
1101Obtains the names of all navigation destination pages in the navigation stack.
1102
1103**Atomic service API**: This API can be used in atomic services since API version 11.
1104
1105**System capability**: SystemCapability.ArkUI.ArkUI.Full
1106
1107**Return value**
1108
1109| Type            | Description                        |
1110| -------------- | -------------------------- |
1111| Array<string\> | Names of all navigation destination pages in the navigation stack.|
1112
1113### getParamByIndex<sup>10+</sup>
1114
1115getParamByIndex(index: number): unknown | undefined
1116
1117Obtains the parameter information of the navigation destination page specified by **index**.
1118
1119**Atomic service API**: This API can be used in atomic services since API version 11.
1120
1121**System capability**: SystemCapability.ArkUI.ArkUI.Full
1122
1123**Parameters**
1124
1125| Name   | Type    | Mandatory  | Description                    |
1126| ----- | ------ | ---- | ---------------------- |
1127| index | number | Yes   | Index of the navigation destination page.|
1128
1129**Return value**
1130
1131| Type       | Description                        |
1132| --------- | -------------------------- |
1133| unknown   | Parameter information of the matching navigation destination page.|
1134| undefined | Returned if the provided index is invalid.    |
1135
1136### getParamByName<sup>10+</sup>
1137
1138getParamByName(name: string): Array<unknown\>
1139
1140Obtains the parameter information of all the navigation destination pages that match **name**.
1141
1142**Atomic service API**: This API can be used in atomic services since API version 11.
1143
1144**System capability**: SystemCapability.ArkUI.ArkUI.Full
1145
1146**Parameters**
1147
1148| Name  | Type    | Mandatory  | Description                 |
1149| ---- | ------ | ---- | ------------------- |
1150| name | string | Yes   | Name of the navigation destination page.|
1151
1152**Return value**
1153
1154| Type             | Description                               |
1155| --------------- | --------------------------------- |
1156| Array<unknown\> | Parameter information of all the matching navigation destination pages.|
1157
1158### getIndexByName<sup>10+</sup>
1159
1160getIndexByName(name: string): Array<number\>
1161
1162Obtains the indexes of all the navigation destination pages that match **name**.
1163
1164**Atomic service API**: This API can be used in atomic services since API version 11.
1165
1166**System capability**: SystemCapability.ArkUI.ArkUI.Full
1167
1168**Parameters**
1169
1170| Name  | Type    | Mandatory  | Description                 |
1171| ---- | ------ | ---- | ------------------- |
1172| name | string | Yes   | Name of the navigation destination page.|
1173
1174**Return value**
1175
1176| Type            | Description                               |
1177| -------------- | --------------------------------- |
1178| Array<number\> | Indexes of all the matching navigation destination pages.|
1179
1180### size<sup>10+</sup>
1181
1182size(): number
1183
1184Obtains the stack size.
1185
1186**Atomic service API**: This API can be used in atomic services since API version 11.
1187
1188**System capability**: SystemCapability.ArkUI.ArkUI.Full
1189
1190**Return value**
1191
1192| Type    | Description    |
1193| ------ | ------ |
1194| number | Stack size.|
1195
1196### disableAnimation<sup>11+</sup>
1197
1198disableAnimation(value: boolean): void
1199
1200Disables or enables the transition animation in the **Navigation** component.
1201
1202**Atomic service API**: This API can be used in atomic services since API version 12.
1203
1204**System capability**: SystemCapability.ArkUI.ArkUI.Full
1205
1206**Parameters**
1207
1208| Name   | Type    | Mandatory  | Description                   |
1209| ----- | ------ | ---- | ---------------------- |
1210| value | boolean | Yes  | Whether to disable the transition animation.<br>Default value: **false**|
1211
1212### getParent<sup>11+</sup>
1213
1214getParent(): NavPathStack | null
1215
1216Obtains the parent navigation path stack.<br>When a **Navigation** component is nested (directly or indirectly) insider another **Navigation** component, the internal one can obtain the navigation path stack of the external one.
1217
1218**Atomic service API**: This API can be used in atomic services since API version 11.
1219
1220**System capability**: SystemCapability.ArkUI.ArkUI.Full
1221
1222**Return value**
1223
1224| Type    | Description    |
1225| ------ | ------ |
1226| [NavPathStack](#navpathstack10) \| null | Navigation path stack of the external **Navigation** component inside which the current **Navigation** component is nested. If no nesting is involved, **null** is returned.|
1227
1228### setInterception<sup>12+</sup>
1229
1230setInterception(interception: NavigationInterception): void
1231
1232Sets the interception callback for navigation page redirection.
1233
1234**Atomic service API**: This API can be used in atomic services since API version 12.
1235
1236**System capability**: SystemCapability.ArkUI.ArkUI.Full
1237
1238**Parameters**
1239
1240| Name   | Type    | Mandatory  | Description                    |
1241| ---- | ---- | --- | ---|
1242|interception| [NavigationInterception](#navigationinterception12)| Yes| Object to be intercepted during navigation redirection.|
1243
1244## NavPathInfo<sup>10+</sup>
1245
1246Provides the navigation page information.
1247
1248### constructor
1249
1250constructor(name: string, param: unknown, onPop?: Callback\<PopInfo>, isEntry?: boolean)
1251
1252**Atomic service API**: This API can be used in atomic services since API version 11.
1253
1254**System capability**: SystemCapability.ArkUI.ArkUI.Full
1255
1256| Name   | Type     | Mandatory  | Description                  |
1257| ----- | ------- | ---- | --------------------- |
1258| name  | string  | Yes   | Name of the navigation destination page.  |
1259| param | unknown | Yes   | Detailed parameters of the navigation destination page.|
1260| onPop<sup>11+</sup> | Callback\<[PopInfo](#popinfo11)> | No| Callback returned when [pop](#pop11) is called on the navigation destination page. It is invoked only after the **result** parameter is set in [pop](#pop11).|
1261| isEntry<sup>12+</sup> | boolean | No| Whether the navigation destination page is the entry page.<br>Default value: **false**<br>The value of this parameter is reviewed or reset under the following conditions:<br>- When a global back event is triggered on the current navigation destination page.<br> - When the application is switched to the background.<br>**NOTE**<br>The navigation destination page serving as an entry does not respond to the in-app global back events; instead, it directly triggers the global back event between applications.|
1262
1263### Properties
1264
1265**System capability**: SystemCapability.ArkUI.ArkUI.Full
1266
1267| Name   | Type     | Mandatory  | Description                  |
1268| ----- | ------- | ---- | --------------------- |
1269| name  | string  | Yes   | Name of the navigation destination page.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
1270| param | unknown | No   | Detailed parameters of the navigation destination page.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
1271| onPop<sup>11+</sup> | Callback\<[PopInfo](#popinfo11)> | No| Callback returned when [pop](#pop11) is called on the navigation destination page. It is invoked only after the **result** parameter is set in [pop](#pop11).<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
1272| isEntry<sup>12+</sup> | boolean | No| Whether the navigation destination page is the entry page.<br>Default value: **false**<br>The value of this parameter is reviewed or reset under the following conditions:<br>- When a global back event is triggered on the current navigation destination page.<br> - When the application is switched to the background.<br>**NOTE**<br>The navigation destination page serving as an entry does not respond to the in-app global back events; instead, it directly triggers the global back event between applications.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
1273
1274## PopInfo<sup>11+</sup>
1275
1276Provides the callback information returned when a page is popped out of the navigation stack.
1277
1278**Atomic service API**: This API can be used in atomic services since API version 12.
1279
1280**System capability**: SystemCapability.ArkUI.ArkUI.Full
1281
1282| Name| Type| Mandatory| Description|
1283|------|-----|-----|-----|
1284| info | [NavPathInfo](#navpathinfo10) | Yes| Information about the current page when a back action is performed. The value is automatically obtained by the system.|
1285| result | Object | Yes| Result returned when a back action is performed. You must customize the object.|
1286
1287## NavContentInfo<sup>11+</sup>
1288
1289Provides the destination information.
1290
1291**Atomic service API**: This API can be used in atomic services since API version 12.
1292
1293**System capability**: SystemCapability.ArkUI.ArkUI.Full
1294
1295| Name | Type | Mandatory | Description |
1296|-------|-------|------|-------|
1297| name | string | No| Name of the navigation destination. If the view is a root view (**NavBar**), the return value is **undefined**.|
1298| index | number | Yes| Index of the navigation destination in the navigation stack. If the view is a root view (**NavBar**), the return value is **-1**.|
1299| mode | [NavDestinationMode](ts-basic-components-navdestination.md#navdestinationmode11) | No| Mode of the navigation destination. If the view is a root view (**NavBar**), the return value is **undefined**.|
1300| param<sup>12+</sup> | Object | No| Parameters loaded on the navigation destination page.|
1301| navDestinationId<sup>12+</sup> | string | No| Unique identifier of the navigation destination page.|
1302
1303## NavigationAnimatedTransition<sup>11+</sup>
1304
1305Defines the custom transition animation protocol. You need to implement this protocol to define the redirection animation of the navigation route.
1306
1307**Atomic service API**: This API can be used in atomic services since API version 12.
1308
1309**System capability**: SystemCapability.ArkUI.ArkUI.Full
1310
1311| Name| Type| Mandatory| Description|
1312|------|-----|-----|------|
1313| timeout | number | No| Animation timeout time.<br> Unit: ms<br> Default value: no default value for interactive animations; 1000 ms for non-interactive animations.|
1314| transition | (transitionProxy : [NavigationTransitionProxy](#navigationtransitionproxy-11)) =&gt; void | Yes| Callback for executing the custom transition animation.<br> **transitionProxy**: proxy for the custom transition animation.|
1315| onTransitionEnd | (success: boolean) => void | No| Callback invoked when the transition is complete.<br> **success**: whether the transition is successful.|
1316| isInteractive<sup>12+</sup> | boolean | No| Whether the transition animation is interactive.<br> Default value: **false**|
1317
1318## NavigationTransitionProxy <sup>11+</sup>
1319
1320Implements a custom transition animation proxy.
1321
1322**System capability**: SystemCapability.ArkUI.ArkUI.Full
1323
1324### Attributes
1325
1326**Atomic service API**: This API can be used in atomic services since API version 12.
1327
1328**System capability**: SystemCapability.ArkUI.ArkUI.Full
1329
1330| Name| Type | Mandatory| Description |
1331|------|-------|-----|-------|
1332| from | [NavContentInfo](#navcontentinfo11) | Yes| Information about the exit page.|
1333| to | [NavContentInfo](#navcontentinfo11) | Yes| Information about the enter page.|
1334| isInteractive<sup>12+</sup> | boolean | No| Whether the transition animation is interactive.|
1335
1336### finishTransition
1337
1338finishTransition(): void;
1339
1340Finishes this custom transition animation. This API must be manually called to end the animation. Otherwise, the system ends the animation when the timeout expires.
1341
1342**Atomic service API**: This API can be used in atomic services since API version 12.
1343
1344**System capability**: SystemCapability.ArkUI.ArkUI.Full
1345
1346### cancelTransition<sup>12+</sup>
1347
1348cancelTransition?(): void;
1349
1350Cancels this interactive transition animation, restoring the navigation stack to its state before page redirection. (Non-interactive transition animations cannot be canceled.)
1351
1352**Atomic service API**: This API can be used in atomic services since API version 12.
1353
1354**System capability**: SystemCapability.ArkUI.ArkUI.Full
1355
1356### updateTransition<sup>12+</sup>
1357
1358updateTransition?(progress: number): void;
1359
1360Updates the progress of this interactive transition animation. (Non-interactive animations do not support setting the animation progress).
1361
1362**Atomic service API**: This API can be used in atomic services since API version 12.
1363
1364**System capability**: SystemCapability.ArkUI.ArkUI.Full
1365
1366**Parameters**
1367
1368| Name| Type| Mandatory| Description|
1369|------|------|------|-----|
1370| progress | number | Yes| Progress percentage of the interactive transition animation. The value ranges from 0 to 1.|
1371
1372## NavigationInterception<sup>12+</sup>
1373
1374Describes the object to be intercepted during navigation redirection.
1375
1376**Atomic service API**: This API can be used in atomic services since API version 12.
1377
1378**System capability**: SystemCapability.ArkUI.ArkUI.Full
1379
1380| Name   | Type    | Mandatory| Description   |
1381| ---- | ----- | ----- | ----   |
1382| willShow | [InterceptionShowCallback](#interceptionshowcallback12) | No| Interception before page redirection, allowing for stack operations. The setting takes effect in the current redirection.|
1383| didShow | [InterceptionShowCallback](#interceptionshowcallback12) | No| Callback after page redirection. The setting takes effect in the next redirection.|
1384| modeChange | [InterceptionModeCallback](#interceptionmodecallback12) | No| Callback invoked when the display mode of the **Navigation** component switches between single-column and dual-column.|
1385
1386### InterceptionShowCallback<sup>12+</sup>
1387
1388type InterceptionShowCallback = (from: NavDestinationContext|NavBar, to: NavDestinationContext|NavBar, operation: NavigationOperation, isAnimated: boolean) => void
1389
1390Represents the interception callback before and after the navigation page.
1391
1392**Atomic service API**: This API can be used in atomic services since API version 12.
1393
1394**System capability**: SystemCapability.ArkUI.ArkUI.Full
1395
1396| Name | Type   | Mandatory| Description             |
1397| ------ | ------ | ---- | ---------------- |
1398| from | [NavDestinationContext](ts-basic-components-navdestination.md#navdestinationcontext11) \|[NavBar](#navbar12) | Yes|  Information about the top page in the navigation stack before page redirection. The value **navBar** indicates that the top page is the home page.|
1399| to | [NavDestinationContext](ts-basic-components-navdestination.md#navdestinationcontext11) \|[NavBar](#navbar12) | Yes| Information about the top page in the navigation stack after page redirection. The value **navBar** indicates that the top page is the home page.|
1400| operation | [NavigationOperation](#navigationoperation11) | Yes| Current page redirection type.|
1401| isAnimated | boolean | Yes| Whether to support transition animation.|
1402
1403### InterceptionModeCallback<sup>12+</sup>
1404
1405type InterceptionModeCallback = (mode: NavigationMode) => void
1406
1407Implements an interception callback triggered when the display mode of the **Navigation** component switches between single-column and dual-column.
1408
1409**Atomic service API**: This API can be used in atomic services since API version 12.
1410
1411**System capability**: SystemCapability.ArkUI.ArkUI.Full
1412
1413| Name | Type   | Mandatory| Description             |
1414| ------ | ------ | ---- | ---------------- |
1415| mode | [NavigationMode](#navigationmode9) | Yes|  Display mode of the navigation bar.|
1416
1417## NavBar<sup>12+</sup>
1418
1419type NavBar = 'navBar'
1420
1421Defines the name of the navigation home page.
1422
1423**Atomic service API**: This API can be used in atomic services since API version 12.
1424
1425**System capability**: SystemCapability.ArkUI.ArkUI.Full
1426
1427| Type    | Description            |
1428| -------- | ---------------- |
1429| 'navBar' | Navigation home page.|
1430
1431## NavigationMenuItem
1432
1433**System capability**: SystemCapability.ArkUI.ArkUI.Full
1434
1435| Name    | Type           | Mandatory  | Description             |
1436| ------ | ------------- | ---- | --------------- |
1437| value  | string \| [Resource<sup>14+<sup>](ts-types.md#resource)       | Yes   | Text of the menu item. Its visibility varies by the API version.<br>API version 9: visible.<br> API version 10: invisible.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
1438| icon   | string \| [Resource<sup>14+<sup>](ts-types.md#resource)       | No   | Icon path of the menu item.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
1439| isEnabled<sup>12+</sup>   | boolean        | No   | Enabled status.<br>**true** (default): enabled<br>**false**: disabled<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
1440| action | () =&gt; void | No   | Callback invoked when the menu item is selected.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
1441| symbolIcon<sup>12+</sup> |  [SymbolGlyphModifier](ts-universal-attributes-attribute-modifier.md)  | No   |Symbol icon for a single option on the menu bar. It has higher priority than **icon**.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
1442
1443## ToolbarItem<sup>10+</sup>
1444
1445**Atomic service API**: This API can be used in atomic services since API version 11.
1446
1447**System capability**: SystemCapability.ArkUI.ArkUI.Full
1448
1449| Name        | Type                                      | Mandatory  | Description                                      |
1450| ---------- | ---------------------------------------- | ---- | ---------------------------------------- |
1451| value      | ResourceStr                              | Yes   | Text of the toolbar item.                           |
1452| icon       | ResourceStr                              | No   | Icon path of the toolbar item.                         |
1453| action     | () =&gt; void                            | No   | Callback invoked when the toolbar item is selected.                           |
1454| status     | [ToolbarItemStatus](#toolbaritemstatus10) | No   | Status of the toolbar item.<br>Default value: **ToolbarItemStatus.NORMAL**|
1455| activeIcon | ResourceStr                              | No   | Icon path of the toolbar item in the active state.               |
1456| symbolIcon<sup>12+</sup> | [SymbolGlyphModifier](ts-universal-attributes-attribute-modifier.md)        | No   | Symbol icon for a single option on the toolbar. It has higher priority than **icon**.<br>**Atomic service API**: This API can be used in atomic services since API version 12.          |
1457| activeSymbolIcon<sup>12+</sup> | [SymbolGlyphModifier](ts-universal-attributes-attribute-modifier.md)              | No   | Symbol icon for a single option on the menu bar when it is in active state. It has higher priority than **icon**.<br>**Atomic service API**: This API can be used in atomic services since API version 12.           |
1458
1459## ToolbarItemStatus<sup>10+</sup>
1460
1461**Atomic service API**: This API can be used in atomic services since API version 11.
1462
1463**System capability**: SystemCapability.ArkUI.ArkUI.Full
1464
1465| Name    | Description                                                        |
1466| -------- | ------------------------------------------------------------ |
1467| NORMAL   | Normal state. In this state, the toolbar item takes on the default style and can switch to another state-specific style by responding to the hover, press, and focus events.|
1468| DISABLED | Disabled state. In this state, the toolbar item is disabled and does not allow for user interactions.|
1469| ACTIVE   | Active state. In this state, the toolbar item can update its icon to the one specified by **activeIcon** by responding to a click event.|
1470
1471## NavigationTitleMode
1472
1473**Atomic service API**: This API can be used in atomic services since API version 11.
1474
1475**System capability**: SystemCapability.ArkUI.ArkUI.Full
1476
1477| Name| Description                                                        |
1478| ---- | ------------------------------------------------------------ |
1479| Free | When the content is more than one screen in a scrollable component, the main title shrinks as the content scrolls down (the subtitle fades out with its size remaining unchanged) and restores as the content scrolls up to the top.<br>**NOTE**<br>The effect where the main title's size changes in response to content scrolling is effective only when **title** is set to **ResourceStr** or **NavigationCommonTitle**. If **title** is set to any other value type, the main title changes in mere location when pulled down.<br>For this effect to work when the content is less than one screen in a scrollable component, set the **options** parameter of the scrollable component's [edgeEffect](ts-container-list.md#edgeeffect) attribute to **true**. In the non-scrolling state, the height of the title bar is the same as in **Full** mode; in the scrolling state, the minimum height of the title bar is the same as in **Mini** mode.|
1480| Mini | The title is fixed at mini mode.<br>Default value:<br>In versions earlier than API version 12, if there is only a main title, the title bar height is 56 vp; if there is both a main title and a subtitle, the title bar height is 82 vp.<br> Since API version 12, the title bar height is 56 vp.|
1481| Full | The title is fixed at full mode.<br>Default value: If there is only a main title, the title bar height is 112 vp; if there is both a main title and a subtitle, the title bar height is 138 vp.|
1482
1483## NavigationCommonTitle<sup>9+</sup>
1484
1485**Atomic service API**: This API can be used in atomic services since API version 11.
1486
1487**System capability**: SystemCapability.ArkUI.ArkUI.Full
1488
1489| Name  | Type    | Mandatory  | Description    |
1490| ---- | ------ | ---- | ------ |
1491| main | string \| [Resource<sup>14+<sup>](ts-types.md#resource) | Yes   | Main title.|
1492| sub  | string \| [Resource<sup>14+<sup>](ts-types.md#resource) | Yes   | Subtitle.|
1493
1494## NavigationCustomTitle<sup>9+</sup>
1495
1496**Atomic service API**: This API can be used in atomic services since API version 11.
1497
1498**System capability**: SystemCapability.ArkUI.ArkUI.Full
1499
1500| Name     | Type                                      | Mandatory  | Description     |
1501| ------- | ---------------------------------------- | ---- | -------- |
1502| builder | [CustomBuilder](ts-types.md#custombuilder8) | Yes   | Content of the title bar.|
1503| height  | [TitleHeight](ts-appendix-enums.md#titleheight9) \| [Length](ts-types.md#length) | Yes   | Height of the title bar.|
1504
1505## NavBarPosition<sup>9+</sup>
1506
1507**Atomic service API**: This API can be used in atomic services since API version 11.
1508
1509**System capability**: SystemCapability.ArkUI.ArkUI.Full
1510
1511| Name | Description                            |
1512| ----- | -------------------------------- |
1513| Start | When two columns are displayed, the main column is at the start of the main axis.|
1514| End   | When two columns are displayed, the main column is at the end of the main axis.|
1515
1516## NavigationMode<sup>9+</sup>
1517
1518**Atomic service API**: This API can be used in atomic services since API version 11.
1519
1520**System capability**: SystemCapability.ArkUI.ArkUI.Full
1521
1522| Name | Description                                                        |
1523| ----- | ------------------------------------------------------------ |
1524| Stack | The navigation bar and content area are displayed independently of each other, which are equivalent to two pages.                    |
1525| Split | The navigation bar and content area are displayed in different columns.<br>The values of **navBarWidthRange** are represented by [minNavBarWidth,maxNavBarWidth].<br>1. When the value of **navBarWidth** is beyond the value range specified by **navBarWidthRange**, **navBarWidth** is set according to the following rules:<br>Value of **navBarWidth** < Value of **minNavBarWidth**: The value of **navBarWidth** is changed to that of **minNavBarWidth**.<br>Value of **navBarWidth** > Value of **maxNavBarWidth** and Result of [Component width - Value of **minContentWidth** - Divider width (1 vp)] > Value of **maxNavBarWidth**: The value of **navBarWidth** is changed to that of **maxNavBarWidth**.<br>Value of **navBarWidth** > Value of **maxNavBarWidth** and Result of [Component width - Value of **minContentWidth** - Divider width (1 vp)] < Value of **maxNavBarWidth**: The value of **navBarWidth** is changed to that of **minNavBarWidth**.<br>Value of **navBarWidth** > Value of **maxNavBarWidth** and Component width - Value of **minContentWidth** - Divider width (1 vp) is within the value range specified by **navBarWidthRange**: The value of **navBarWidth** is changed to Component width - Value of **minContentWidth** - Divider width (1 vp).<br>2. When the value of **navBarWidth** is within the value range specified by **navBarWidthRange**, **navBarWidth** is set according to the following rules:<br>Value of **minNavBarWidth** + Value of **minContentWidth** + Divider width (1 vp) > = Component width: The value of **navBarWidth** is changed to that of **minNavBarWidth**.<br>Value of **minNavBarWidth** + Value of **minContentWidth** + Divider width (1 vp) < Component width and Value of **navBarWidth** + Value of **minContentWidth** + Divider width (1 vp) > = Component width: The value of **navBarWidth** is changed to Component width - Value of **minContentWidth** - Divider width (1 vp).<br>Value of **minNavBarWidth** + Value of **minContentWidth** + Divider width (1 vp) < Component width and Value of **navBarWidth** + Value of **minContentWidth** + Divider width (1 vp) < Component width: The value of **navBarWidth** is the set value. <br>3. When the component size is decreased, the content area is shrunk until its width reaches the value defined by **minContentWidth**, and then the navigation bar is shrunk until its width reaches the value defined by **minNavBarWidth**; if the component size is further decreased, the content area is further shrunk until it disappears, and then navigation bar is shrunk.<br>4. When the navigation bar is set to a fixed size and the component size is continuously decreased, the navigation bar is shrunk.<br>5. If only **navBarWidth** is set, the width of the navigation bar is fixed at the value of **navBarWidth**, and the divider cannot be dragged.|
1526| Auto  | In API version 9 and earlier versions: If the window width is greater than or equal to 520 vp, the Split mode is used; otherwise, the Stack mode is used.<br>In API version 10 and later versions: If the window width is greater than or equal to 600 vp, the Split mode is used; otherwise, the Stack mode is used. 600 vp = minNavBarWidth (240 vp) + minContentWidth (360 vp).|
1527
1528## NavigationOperation<sup>11+</sup>
1529
1530**Atomic service API**: This API can be used in atomic services since API version 12.
1531
1532**System capability**: SystemCapability.ArkUI.ArkUI.Full
1533
1534| Name   | Description|
1535|---------|------|
1536|PUSH | The transition is enter transition.|
1537|POP | The transition is exit transition.|
1538| REPLACE | The transition is page replacement.|
1539
1540## BarStyle<sup>12+</sup>
1541
1542Enumerates the layout styles of the title bar and toolbar. Note that this API is not supported for the toolbar in **NavDestination**.
1543
1544**System capability**: SystemCapability.ArkUI.ArkUI.Full
1545
1546| Name   | Description|
1547|---------|------|
1548|STANDARD | In this mode, the title bar or toolbar is laid out above the content area.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
1549|STACK | In this mode, the title bar or toolbar is overlaid on top of the content area.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
1550|SAFE_AREA_PADDING<sup>14+</sup> | In this mode, the title bar or toolbar is configured to respect the [component-level safe area](./ts-universal-attributes-size.md#safeareapadding14).<br>**Atomic service API**: This API can be used in atomic services since API version 14.|
1551
1552## NavigationTitleOptions<sup>11+</sup>
1553
1554**System capability**: SystemCapability.ArkUI.ArkUI.Full
1555
1556| Name    | Type           | Mandatory  | Description             |
1557| ------ | ------------- | ---- | --------------- |
1558| backgroundColor | [ResourceColor](ts-types.md#resourcecolor)  | No   | Background color of the title bar. If this parameter is not set, the default color is used.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
1559| backgroundBlurStyle   | [BlurStyle](ts-universal-attributes-background.md#blurstyle9)        | No   | Background blur style of the title bar. If this parameter is not set, the background blur effect is disabled.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
1560| barStyle<sup>12+</sup>   | [BarStyle](#barstyle12)        | No   | Layout style of the title bar.<br>Default value: **BarStyle.STANDARD**<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
1561| paddingStart<sup>12+</sup>   | [LengthMetrics](../js-apis-arkui-graphics.md#lengthmetrics12)        | No   | Padding at the start of the title bar.<br>Only supported in one of the following scenarios:<br>1. Displaying the back icon, that is, [hideBackButton](#hidebackbutton) is **false**<br>2. Using a non-custom title, that is, the [title value](#title) type is **ResourceStr** or **NavigationCommonTitle**<br>Default value:<br>LengthMetrics.resource(**$r('sys.float.margin_left')**)<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
1562| paddingEnd<sup>12+</sup>   | [LengthMetrics](../js-apis-arkui-graphics.md#lengthmetrics12)        | No   | Padding at the end of the title bar.<br>Only supported in one of the following scenarios:<br>1. Using a non-custom menu, that is, the [menu value](#menus) is Array&lt;NavigationMenuItem&gt;<br>2. Using a non-custom menu without a menu in the upper right corner, that is, the [title value](#title) type is **ResourceStr** or **NavigationCommonTitle**<br>Default value:<br>LengthMetrics.resource(**$r('sys.float.margin_right')**)<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
1563| mainTitleModifier<sup>13+</sup>   | [TextModifier](./ts-universal-attributes-attribute-modifier.md)  | No| Main title attribute modifier.<br>Notes for using this modifier:<br>1. Attribute settings configured by this modifier will override the system's default attribute settings. For example, if the modifier is used to set font size attributes, such as **fontSize**, **maxFontSize**, and **minFontSize**, the settings will take precedence over the system's default settings for size-related attributes.<br>2. If no modifier is used or an invalid value is set, the system reverts to its default settings.<br>3. In [Free](#navigationtitlemode) mode, setting the font size will disable the effect where the main title's size changes in response to content scrolling.<br>**Atomic service API**: This API can be used in atomic services since API version 13.|
1564| subTitleModifier<sup>13+</sup>   | [TextModifier](./ts-universal-attributes-attribute-modifier.md)  | No| Subtitle attribute modifier.<br>Notes for using this modifier:<br>1. Attribute settings configured by this modifier will override the system's default attribute settings. For example, if the modifier is used to set font size attributes, such as **fontSize**, **maxFontSize**, and **minFontSize**, the settings will take precedence over the system's default settings for size-related attributes.<br>2. If no modifier is used or an invalid value is set, the system reverts to its default settings.<br>**Atomic service API**: This API can be used in atomic services since API version 13.|
1565| enableHoverMode<sup>13+</sup>   | boolean | No| Whether to enable the hover mode.<br>Observe the following when using this API:<br>1. Make sure the **Navigation** component is in full screen.<br>2. When the title bar is in [Free](#navigationtitlemode) display mode or in [STANDARD](#barstyle12) layout style, this API has no effect.<br>Default value: **false**<br>**Atomic service API**: This API can be used in atomic services since API version 13.|
1566
1567## NavigationToolbarOptions<sup>11+</sup>
1568
1569**System capability**: SystemCapability.ArkUI.ArkUI.Full
1570
1571| Name    | Type           | Mandatory  | Description             |
1572| ------ | ------------- | ---- | --------------- |
1573| backgroundColor | [ResourceColor](ts-types.md#resourcecolor)  | No   | Background color of the toolbar. If this parameter is not set, the default color is used.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
1574| backgroundBlurStyle   | [BlurStyle](ts-universal-attributes-background.md#blurstyle9)        | No   | Background blur style of the toolbar. If this parameter is not set, the background blur effect is disabled.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
1575| barStyle<sup>14+</sup>   | [BarStyle](#barstyle12)        | No   | Layout style of the toolbar.<br>**Atomic service API**: This API can be used in atomic services since API version 14.|
1576
1577## LaunchMode<sup>12+</sup>
1578
1579**Atomic service API**: This API can be used in atomic services since API version 12.
1580
1581**System capability**: SystemCapability.ArkUI.ArkUI.Full
1582
1583| Name   | Description|
1584| --------- | ------ |
1585| STANDARD | Default navigation stack operation mode.<br>In this mode, push operations add the specified **NavDestination** page to the stack; replace operations replace the current top **NavDestination** page.|
1586| MOVE_TO_TOP_SINGLETON | This mode searches from the bottom to the top of the navigation stack. If a **NavDestination** page with the specified name exists, it moves that page to the top of the stack (for a replace operation, it replaces the last top **NavDestination** page with the specified one); otherwise, it behaves like **STANDARD**.|
1587| POP_TO_SINGLETON | This mode searches from the bottom to the top of the navigation stack. If a **NavDestination** page with the specified name exists, it removes all **NavDestination** pages above it(for a replace operation, it replaces the last top **NavDestination** page with the specified one); otherwise, it behaves like **STANDARD**.|
1588| NEW_INSTANCE | This mode creates an instance of **NavDestination**. Compared with **STANDARD**, this mode does not reuse the instance with the same name in the stack.|
1589
1590## NavigationOptions<sup>12+</sup>
1591
1592**Atomic service API**: This API can be used in atomic services since API version 12.
1593
1594**System capability**: SystemCapability.ArkUI.ArkUI.Full
1595
1596| Name    | Type           | Mandatory  | Description             |
1597| ------ | ------------- | ---- | --------------- |
1598| launchMode | [LaunchMode](#launchmode12)  | No   | Navigation stack operation mode.<br>Default value: **LaunchMode.STANDARD**|
1599| animated   | boolean  | No   | Whether to support transition animation.<br>Default value: **true**|
1600
1601## SystemBarStyle<sup>12+</sup>
1602
1603type SystemBarStyle = SystemBarStyle
1604
1605Describes the properties of the status bar. These properties are valid for the page-level status bar.
1606
1607**Atomic service API**: This API can be used in atomic services since API version 12.
1608
1609**System capability**: SystemCapability.ArkUI.ArkUI.Full
1610
1611| Type    | Description              |
1612| -------- | ------------------ |
1613| [SystemBarStyle](../js-apis-window.md#systembarstyle12)   | Color of the text on the status bar. The default value is **'#0xE5FFFFFF'**.|
1614
1615## Example
1616
1617The outcome of the sample code may vary depending on the actual device used. The system routing table does not work with DevEco Studio Previewer, cross-platform functionality, or emulators.
1618
1619### Example 1: Implementing a Navigation Page Layout
1620
1621This example demonstrates the layout of a navigation page, including the title bar (**title**), menu bar (**menus**), content area, and toolbar (**toolbarConfiguration**).
1622
1623```ts
1624// xxx.ets
1625class A {
1626  text: string = ''
1627  num: number = 0
1628}
1629
1630@Entry
1631@Component
1632struct NavigationExample {
1633  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1634  @State currentIndex: number = 0
1635
1636  @Builder
1637  NavigationTitle() {
1638    Column() {
1639      Text('Title')
1640        .fontColor('#182431')
1641        .fontSize(30)
1642        .lineHeight(41)
1643        .fontWeight(700)
1644      Text('subtitle')
1645        .fontColor('#182431')
1646        .fontSize(14)
1647        .lineHeight(19)
1648        .opacity(0.4)
1649        .margin({ top: 2, bottom: 20 })
1650    }.alignItems(HorizontalAlign.Start)
1651  }
1652
1653  @Builder
1654  NavigationMenus() {
1655    Row() {
1656      Image('resources/base/media/ic_public_add.svg')
1657        .width(24)
1658        .height(24)
1659      Image('resources/base/media/ic_public_add.svg')
1660        .width(24)
1661        .height(24)
1662        .margin({ left: 24 })
1663      Image('common/ic_public_more.svg')
1664        .width(24)
1665        .height(24)
1666        .margin({ left: 24 })
1667    }
1668  }
1669
1670  build() {
1671    Column() {
1672      Navigation() {
1673        TextInput({ placeholder: 'search...' })
1674          .width('90%')
1675          .height(40)
1676          .backgroundColor('#FFFFFF')
1677          .margin({ top: 8 })
1678
1679        List({ space: 12, initialIndex: 0 }) {
1680          ForEach(this.arr, (item: number) => {
1681            ListItem() {
1682              Text('' + item)
1683                .width('90%')
1684                .height(72)
1685                .backgroundColor('#FFFFFF')
1686                .borderRadius(24)
1687                .fontSize(16)
1688                .fontWeight(500)
1689                .textAlign(TextAlign.Center)
1690            }
1691          }, (item: number) => item.toString())
1692        }
1693        .height(324)
1694        .width('100%')
1695        .margin({ top: 12, left: '10%' })
1696      }
1697      .title(this.NavigationTitle)
1698      .menus(this.NavigationMenus)
1699      .titleMode(NavigationTitleMode.Full)
1700      .toolbarConfiguration([
1701        {
1702          value: $r("app.string.navigation_toolbar_add"),
1703          icon: $r("app.media.ic_public_highlightsed")
1704        },
1705        {
1706          value: $r("app.string.navigation_toolbar_app"),
1707          icon: $r("app.media.ic_public_highlights")
1708        },
1709        {
1710          value: $r("app.string.navigation_toolbar_collect"),
1711          icon: $r("app.media.ic_public_highlights")
1712        }
1713      ])
1714      .hideTitleBar(false)
1715      .hideToolBar(false)
1716      .onTitleModeChange((titleModel: NavigationTitleMode) => {
1717        console.info('titleMode' + titleModel)
1718      })
1719    }.width('100%').height('100%').backgroundColor('#F1F3F5')
1720  }
1721}
1722```
1723
1724![en-us_image_navigation](figures/en-us_image_navigation.png)
1725
1726
1727
1728### Example 2: Using NavPathStack Methods
1729
1730This example demonstrates the use of methods in **NavPathStack** and route interception.
1731
1732```ts
1733// Index.ets
1734
1735@Entry
1736@Component
1737struct NavigationExample {
1738  pageInfos: NavPathStack = new NavPathStack()
1739  isUseInterception: boolean = false;
1740
1741  registerInterception() {
1742    this.pageInfos.setInterception({
1743      // Interception before page redirection, allowing for stack operations. The setting takes effect in the current redirection.
1744      willShow: (from: NavDestinationContext | "navBar", to: NavDestinationContext | "navBar",
1745        operation: NavigationOperation, animated: boolean) => {
1746        if (!this.isUseInterception) {
1747          return;
1748        }
1749        if (typeof to === "string") {
1750          console.log("target page is navigation home");
1751          return;
1752        }
1753        // Redirect the target page from pageTwo to pageOne.
1754        let target: NavDestinationContext = to as NavDestinationContext;
1755        if (target.pathInfo.name === 'pageTwo') {
1756          target.pathStack.pop();
1757          target.pathStack.pushPathByName('pageOne', null);
1758        }
1759      },
1760      // Callback invoked after the page is navigated. Stack operations in this callback are effective in the next navigation.
1761      didShow: (from: NavDestinationContext | "navBar", to: NavDestinationContext | "navBar",
1762        operation: NavigationOperation, isAnimated: boolean) => {
1763        if (!this.isUseInterception) {
1764          return;
1765        }
1766        if (typeof from === "string") {
1767          console.log("current transition is from navigation home");
1768        } else {
1769          console.log(`current transition is from  ${(from as NavDestinationContext).pathInfo.name}`)
1770        }
1771        if (typeof to === "string") {
1772          console.log("current transition to is navBar");
1773        } else {
1774          console.log(`current transition is to ${(to as NavDestinationContext).pathInfo.name}`);
1775        }
1776      },
1777      // Callback invoked when the display mode of the Navigation component switches between single-column and dual-column.
1778      modeChange: (mode: NavigationMode) => {
1779        if (!this.isUseInterception) {
1780          return;
1781        }
1782        console.log(`current navigation mode is ${mode}`);
1783      }
1784    })
1785  }
1786
1787  build() {
1788    Navigation(this.pageInfos) {
1789      Column() {
1790        Button('pushPath', { stateEffect: true, type: ButtonType.Capsule })
1791          .width('80%')
1792          .height(40)
1793          .margin(20)
1794          .onClick(() => {
1795            this.pageInfos.pushPath({ name:'pageOne'}) // Push the navigation destination page specified by name to the navigation stack.
1796          })
1797        Button('use interception', { stateEffect: true, type: ButtonType.Capsule })
1798          .width('80%')
1799          .height(40)
1800          .margin(20)
1801          .onClick(() => {
1802            this.isUseInterception = !this.isUseInterception;
1803            if (this.isUseInterception) {
1804              this.registerInterception();
1805            } else {
1806              this.pageInfos.setInterception(undefined);
1807            }
1808          })
1809      }
1810    }.title('NavIndex')
1811  }
1812}
1813```
1814```ts
1815// PageOne.ets
1816class TmpClass {
1817  count: number = 10
1818}
1819
1820@Builder
1821export function PageOneBuilder(name: string, param: Object) {
1822  PageOne()
1823}
1824
1825@Component
1826export struct PageOne {
1827  pageInfos: NavPathStack = new NavPathStack()
1828
1829  build() {
1830    NavDestination() {
1831      Column() {
1832        Button('pushPathByName', { stateEffect: true, type: ButtonType.Capsule })
1833          .width('80%')
1834          .height(40)
1835          .margin(20)
1836          .onClick(() => {
1837            let tmp = new TmpClass()
1838            this.pageInfos.pushPathByName('pageTwo', tmp) // Push the navigation destination page specified by name, with the data specified by param, to the navigation stack.
1839          })
1840        Button('singletonLaunchMode', { stateEffect: true, type: ButtonType.Capsule })
1841          .width('80%')
1842          .height(40)
1843          .margin(20)
1844          .onClick(() => {
1845            this.pageInfos.pushPath({ name: 'pageOne' },
1846              { launchMode: LaunchMode.MOVE_TO_TOP_SINGLETON }) // Search from the bottom to the top of the stack. If the page with the specified name exists, move that page to the top of the stack.
1847          })
1848        Button('popToname', { stateEffect: true, type: ButtonType.Capsule })
1849          .width('80%')
1850          .height(40)
1851          .margin(20)
1852          .onClick(() => {
1853            this.pageInfos.popToName('pageTwo') // Pop the first navigation destination page that matches the value of name to the top of the navigation stack.
1854            console.log('popToName' + JSON.stringify(this.pageInfos),
1855              'Return value' + JSON.stringify(this.pageInfos.popToName('pageTwo')))
1856          })
1857        Button('popToIndex', { stateEffect: true, type: ButtonType.Capsule })
1858          .width('80%')
1859          .height(40)
1860          .margin(20)
1861          .onClick(() => {
1862            this.pageInfos.popToIndex(1) // Return the navigation stack to the navigation destination page that matches the value of index.
1863            console.log('popToIndex' + JSON.stringify(this.pageInfos))
1864          })
1865        Button('moveToTop', { stateEffect: true, type: ButtonType.Capsule })
1866          .width('80%')
1867          .height(40)
1868          .margin(20)
1869          .onClick(() => {
1870            this.pageInfos.moveToTop('pageTwo') // Move to the top of the navigation stack the first navigation destination page that matches the value of name.
1871            console.log('moveToTop' + JSON.stringify(this.pageInfos),
1872              'Return value' + JSON.stringify(this.pageInfos.moveToTop('pageTwo')))
1873          })
1874        Button('moveIndexToTop', { stateEffect: true, type: ButtonType.Capsule })
1875          .width('80%')
1876          .height(40)
1877          .margin(20)
1878          .onClick(() => {
1879            this.pageInfos.moveIndexToTop(1) // Move to the top of the navigation stack the navigation destination page that matches the value of index.
1880            console.log('moveIndexToTop' + JSON.stringify(this.pageInfos))
1881          })
1882        Button('clear', { stateEffect: true, type: ButtonType.Capsule })
1883          .width('80%')
1884          .height(40)
1885          .margin(20)
1886          .onClick(() => {
1887            this.pageInfos.clear() // Clear the navigation stack.
1888          })
1889        Button('get', { stateEffect: true, type: ButtonType.Capsule })
1890          .width('80%')
1891          .height(40)
1892          .margin(20)
1893          .onClick(() => {
1894            console.log('-------------------')
1895            console.log('Obtained the names of all pages in the navigation stack', JSON.stringify(this.pageInfos.getAllPathName()))
1896            console.log('Obtained the parameter information of the navigation destination page specified by index.',
1897              JSON.stringify(this.pageInfos.getParamByIndex(1)))
1898            console.log('Obtained the parameter information of all the navigation destination pages that match name.',
1899              JSON.stringify(this.pageInfos.getParamByName('pageTwo')))
1900            console.log('Obtains the indexes of all the navigation destination pages that match name.',
1901              JSON.stringify(this.pageInfos.getIndexByName('pageOne')))
1902            console.log('Obtained the stack size', JSON.stringify(this.pageInfos.size()))
1903          })
1904      }.width('100%').height('100%')
1905    }.title('pageOne')
1906    .onBackPressed(() => {
1907      const popDestinationInfo = this.pageInfos.pop() // Pop the top element out of the navigation stack.
1908      console.log('pop' + 'Return value' + JSON.stringify(popDestinationInfo))
1909      return true
1910    }).onReady((context: NavDestinationContext) => {
1911      this.pageInfos = context.pathStack
1912    })
1913  }
1914}
1915```
1916```ts
1917// PageTwo.ets
1918@Builder
1919export function PageTwoBuilder(name: string, param: Object) {
1920  PageTwo()
1921}
1922
1923@Component
1924export struct PageTwo {
1925  pathStack: NavPathStack = new NavPathStack()
1926  private menuItems: Array<NavigationMenuItem> = [
1927    {
1928      value: "1",
1929      icon: 'resources/base/media/undo.svg',
1930    },
1931    {
1932      value: "2",
1933      icon: 'resources/base/media/redo.svg',
1934      isEnabled: false,
1935    },
1936    {
1937      value: "3",
1938      icon: 'resources/base/media/ic_public_ok.svg',
1939      isEnabled: true,
1940    }
1941  ]
1942
1943  build() {
1944    NavDestination() {
1945      Column() {
1946        Button('pushPathByName', { stateEffect: true, type: ButtonType.Capsule })
1947          .width('80%')
1948          .height(40)
1949          .margin(20)
1950          .onClick(() => {
1951            this.pathStack.pushPathByName('pageOne', null)
1952          })
1953      }.width('100%').height('100%')
1954    }.title('pageTwo')
1955    .menus(this.menuItems)
1956    .onBackPressed(() => {
1957      this.pathStack.pop()
1958      return true
1959    })
1960    .onReady((context: NavDestinationContext) => {
1961      this.pathStack = context.pathStack;
1962      console.log("current page config info is " + JSON.stringify(context.getConfigInRouteMap()))
1963    })
1964  }
1965}
1966```
1967
1968```json
1969// Configure {"routerMap": "$profile:route_map"} in the project configuration file module.json5.
1970// route_map.json
1971{
1972  "routerMap": [
1973    {
1974      "name": "pageOne",
1975      "pageSourceFile": "src/main/ets/pages/PageOne.ets",
1976      "buildFunction": "PageOneBuilder",
1977      "data": {
1978        "description": "this is pageOne"
1979      }
1980    },
1981    {
1982      "name": "pageTwo",
1983      "pageSourceFile": "src/main/ets/pages/PageTwo.ets",
1984      "buildFunction": "PageTwoBuilder"
1985    }
1986  ]
1987}
1988```
1989![navigation.gif](figures/navigation.gif)
1990
1991### Example 3: Setting an Interactive Transition Animation
1992
1993This sample demonstrates how to set a custom transition animation and an interactive transition animation for each **NavDestination** page.
1994
1995```ts
1996// Index.ets
1997import { CustomTransition, AnimateCallback } from './CustomNavigationUtils'
1998
1999@Entry
2000@Component
2001struct NavigationExample {
2002  pageInfos: NavPathStack = new NavPathStack();
2003
2004  aboutToAppear() {
2005    if (this.pageInfos === undefined) {
2006      this.pageInfos = new NavPathStack();
2007    }
2008    this.pageInfos.pushPath({ name: 'pageOne', param: CustomTransition.getInstance().getAnimationId() });
2009  }
2010
2011  build() {
2012    Navigation(this.pageInfos) {
2013    }
2014    .title('NavIndex')
2015    .hideNavBar(true)
2016    .customNavContentTransition((from: NavContentInfo, to: NavContentInfo, operation: NavigationOperation) => {
2017      if (from.mode == NavDestinationMode.DIALOG || to.mode == NavDestinationMode.DIALOG) {
2018        return undefined;
2019      }
2020
2021      // No custom animation for the home page
2022      if (from.index === -1 || to.index === -1) {
2023        return undefined;
2024      }
2025
2026      CustomTransition.getInstance().operation = operation;
2027      if (CustomTransition.getInstance().interactive) {
2028        let customAnimation: NavigationAnimatedTransition = {
2029          onTransitionEnd: (isSuccess: boolean) => {
2030            console.log("===== current transition is " + isSuccess);
2031            CustomTransition.getInstance().recoverState();
2032            CustomTransition.getInstance().proxy = undefined;
2033          },
2034          transition: (transitionProxy: NavigationTransitionProxy) => {
2035            CustomTransition.getInstance().proxy = transitionProxy;
2036            let targetIndex: string | undefined = operation == NavigationOperation.PUSH ?
2037              (to.navDestinationId) : (from.navDestinationId);
2038            if (targetIndex) {
2039              CustomTransition.getInstance().fireInteractiveAnimation(targetIndex, operation);
2040            }
2041          },
2042          isInteractive: CustomTransition.getInstance().interactive
2043        }
2044        return customAnimation;
2045      }
2046      let customAnimation: NavigationAnimatedTransition = {
2047        onTransitionEnd: (isSuccess: boolean) => {
2048          console.log(`current transition result is ${isSuccess}`)
2049        },
2050        timeout: 7000,
2051        // When the transition starts, the system calls this method and passes in the transition context proxy object.
2052        transition: (transitionProxy: NavigationTransitionProxy) => {
2053          if (!from.navDestinationId || !to.navDestinationId) {
2054            return;
2055          }
2056          // Obtain the corresponding transition animation callback from the CustomTransition class based on the sequence of subpages.
2057          let fromParam: AnimateCallback = CustomTransition.getInstance().getAnimateParam(from.navDestinationId);
2058          let toParam: AnimateCallback = CustomTransition.getInstance().getAnimateParam(to.navDestinationId);
2059          if (operation == NavigationOperation.PUSH) {
2060            if (toParam.start) {
2061              toParam.start(true, false);
2062            }
2063            animateTo({
2064              duration: 500, onFinish: () => {
2065                transitionProxy.finishTransition();
2066              }
2067            }, () => {
2068              if (toParam.finish) {
2069                toParam.finish(true, false);
2070              }
2071            })
2072          } else {
2073            if (fromParam.start) {
2074              fromParam.start(true, true);
2075            }
2076            animateTo({
2077              duration: 500, onFinish: () => {
2078                transitionProxy.finishTransition();
2079              }
2080            }, () => {
2081              if (fromParam.finish) {
2082                fromParam.finish(true, true);
2083              }
2084            })
2085          }
2086        }
2087      };
2088      return customAnimation;
2089    })
2090  }
2091}
2092```
2093
2094```ts
2095// PageOne.ets
2096import { CustomTransition } from './CustomNavigationUtils';
2097
2098@Builder
2099export function PageOneBuilder(name: string, param: Object) {
2100  PageOne()
2101}
2102
2103@Component
2104export struct PageOne {
2105  pageInfos: NavPathStack = new NavPathStack();
2106  @State translateX: string = '0';
2107  pageId: string = '';
2108  rectWidth: number = 0;
2109  interactive: boolean = false;
2110
2111  registerCallback() {
2112    CustomTransition.getInstance().registerNavParam(this.pageId, (isPush: boolean, isExit: boolean) => {
2113      if (isPush) {
2114        this.translateX = '100%';
2115      } else {
2116        this.translateX = '0';
2117      }
2118    }, (isPush: boolean, isExit: boolean) => {
2119      if (isPush) {
2120        this.translateX = '0';
2121      } else {
2122        this.translateX = '100%';
2123      }
2124    }, (isPush: boolean, isExit: boolean) => {
2125      this.translateX = '0';
2126    }, (operation: NavigationOperation) => {
2127      if (operation == NavigationOperation.PUSH) {
2128        this.translateX = '100%';
2129        animateTo({
2130          duration: 1000,
2131          onFinish: () => {
2132            this.translateX = '0';
2133          }
2134        }, () => {
2135          this.translateX = '0';
2136        })
2137      } else {
2138        this.translateX = '0';
2139        animateTo({
2140          duration: 1000,
2141          onFinish: () => {
2142            this.translateX = '0';
2143          }
2144        }, () => {
2145          this.translateX = '100%';
2146        })
2147      }
2148    }, 200);
2149  }
2150
2151  build() {
2152    NavDestination() {
2153      Column() {
2154        Button(`setInteractive`)
2155          .onClick(() => {
2156            CustomTransition.getInstance().interactive = !CustomTransition.getInstance().interactive;
2157            this.interactive = CustomTransition.getInstance().interactive;
2158          })
2159
2160        Button('pushPathByName', { stateEffect: true, type: ButtonType.Capsule })
2161          .width('80%')
2162          .height(40)
2163          .margin(20)
2164          .onClick(() => {
2165            // Push the navigation destination page specified by name, with the data specified by param, to the navigation stack.
2166            this.pageInfos.pushDestinationByName('pageTwo', CustomTransition.getInstance().getAnimationId());
2167          })
2168      }
2169      .size({ width: '100%', height: '100%' })
2170    }
2171    .title('pageOne')
2172    .onDisAppear(() => {
2173      CustomTransition.getInstance().unRegisterNavParam(this.pageId);
2174    })
2175    .onReady((context: NavDestinationContext) => {
2176      this.pageInfos = context.pathStack;
2177      if (context.navDestinationId) {
2178        this.pageId = context.navDestinationId;
2179        this.registerCallback();
2180      }
2181    })
2182    .translate({ x: this.translateX })
2183    .backgroundColor('#F1F3F5')
2184    .gesture(PanGesture()
2185      .onActionStart((event: GestureEvent) => {
2186        this.rectWidth = event.target.area.width as number;
2187        if (event.offsetX < 0) {
2188          this.pageInfos.pushPath({ name: 'pageTwo', param: CustomTransition.getInstance().getAnimationId() });
2189        } else {
2190          this.pageInfos.pop();
2191        }
2192      })
2193      .onActionUpdate((event: GestureEvent) => {
2194        let rate = event.fingerList[0].localX / this.rectWidth;
2195        CustomTransition.getInstance().updateProgress(rate);
2196      })
2197      .onActionEnd((event: GestureEvent) => {
2198        let rate: number = event.fingerList[0].localX / this.rectWidth;
2199        CustomTransition.getInstance().finishInteractiveAnimation(rate);
2200      }))
2201  }
2202}
2203```
2204```ts
2205// PageTwo.ets
2206import { CustomTransition } from './CustomNavigationUtils'
2207
2208@Builder
2209export function PageTwoBuilder(name: string, param: Object) {
2210  PageTwo({ param: param as number })
2211}
2212
2213@Component
2214export struct PageTwo {
2215  pageInfos: NavPathStack = new NavPathStack();
2216  @State translateX: string = '0';
2217  pageId: string = '';
2218  rectWidth: number = 0;
2219  param: number = 0;
2220
2221  registerCallback() {
2222    CustomTransition.getInstance().registerNavParam(this.pageId, (isPush: boolean, isExit: boolean) => {
2223      if (isPush) {
2224        this.translateX = '100%'
2225      } else {
2226        this.translateX = '0';
2227      }
2228    }, (isPush: boolean, isExit: boolean) => {
2229      if (isPush) {
2230        this.translateX = '0';
2231      } else {
2232        this.translateX = '100%'
2233      }
2234    }, (isPush: boolean, isExit: boolean) => {
2235      this.translateX = '0';
2236    }, (operation: NavigationOperation) => {
2237      if (operation == NavigationOperation.PUSH) {
2238        this.translateX = '100%';
2239        animateTo({
2240          duration: 500, onFinish: () => {
2241            this.translateX = '0';
2242          }
2243        }, () => {
2244          this.translateX = '0'
2245        })
2246      } else {
2247        this.translateX = '0';
2248        animateTo({
2249          duration: 500, onFinish: () => {
2250            this.translateX = "0"
2251          }
2252        }, () => {
2253          this.translateX = '100%';
2254        })
2255      }
2256    }, 2000)
2257  }
2258
2259  build() {
2260    NavDestination() {
2261      Column() {
2262        Button('pushPathByName', { stateEffect: true, type: ButtonType.Capsule })
2263          .width('80%')
2264          .height(40)
2265          .margin(20)
2266          .onClick(() => {
2267            // Push the navigation destination page specified by name, with the data specified by param, to the navigation stack.
2268            this.pageInfos.pushPath({ name: 'pageOne', param: CustomTransition.getInstance().getAnimationId() })
2269          })
2270      }
2271      .size({ width: '100%', height: '100%' })
2272    }
2273    .title('pageTwo')
2274    .gesture(PanGesture()
2275      .onActionStart((event: GestureEvent) => {
2276        this.rectWidth = event.target.area.width as number;
2277        if (event.offsetX < 0) {
2278          this.pageInfos.pushPath({ name: 'pageOne', param: CustomTransition.getInstance().getAnimationId() });
2279        } else {
2280          this.pageInfos.pop();
2281        }
2282      })
2283      .onActionUpdate((event: GestureEvent) => {
2284        let rate = event.fingerList[0].localX / this.rectWidth;
2285        CustomTransition.getInstance().updateProgress(rate);
2286      })
2287      .onActionEnd((event: GestureEvent) => {
2288        let rate = event.fingerList[0].localX / this.rectWidth;
2289        CustomTransition.getInstance().finishInteractiveAnimation(rate);
2290      }))
2291    .onAppear(() => {
2292      this.registerCallback();
2293    })
2294    .onDisAppear(() => {
2295      CustomTransition.getInstance().unRegisterNavParam(this.pageId);
2296    })
2297    .onReady((context: NavDestinationContext) => {
2298      this.pageInfos = context.pathStack;
2299      if (context.navDestinationId) {
2300        this.pageId = context.navDestinationId;
2301        this.registerCallback();
2302      }
2303    })
2304    .translate({ x: this.translateX })
2305    .backgroundColor(Color.Yellow)
2306  }
2307}
2308```
2309```ts
2310// CustomNavigationUtils.ets
2311// Custom API to save the transition animation callback and parameters related to a page.
2312export interface AnimateCallback {
2313  finish: ((isPush: boolean, isExit: boolean) => void | undefined) | undefined;
2314  start: ((isPush: boolean, isExit: boolean) => void | undefined) | undefined;
2315  onFinish: ((isPush: boolean, isExit: boolean) => void | undefined) | undefined;
2316  interactive: ((operation: NavigationOperation) => void | undefined) | undefined;
2317  timeout: (number | undefined) | undefined;
2318}
2319
2320const customTransitionMap: Map<string, AnimateCallback> = new Map();
2321
2322export class CustomTransition {
2323  static delegate = new CustomTransition();
2324  interactive: boolean = false;
2325  proxy: NavigationTransitionProxy | undefined = undefined;
2326  private animationId: number = 0;
2327  operation: NavigationOperation = NavigationOperation.PUSH
2328
2329  static getInstance() {
2330    return CustomTransition.delegate;
2331  }
2332
2333  /* Register animation callbacks for a page.
2334   * name: unique ID of the target page
2335   * startCallback: used to set the page state at the start of the animation.
2336   * endCallback: used to set the page state at the end of the animation.
2337   * onFinish: used to perform other operations after the animation ends.
2338   * interactiveCallback: used to handle the interactive part of the transition.
2339   * timeout: timeout for ending the transition.
2340   */
2341  registerNavParam(name: string, startCallback: (operation: boolean, isExit: boolean) => void,
2342    endCallback: (operation: boolean, isExit: boolean) => void,
2343    onFinish: (operation: boolean, isExit: boolean) => void,
2344    interactiveCallback: (operation: NavigationOperation) => void,
2345    timeout: number): void {
2346    if (customTransitionMap.has(name)) {
2347      let param = customTransitionMap.get(name);
2348      if (param != undefined) {
2349        param.start = startCallback;
2350        param.finish = endCallback;
2351        param.timeout = timeout;
2352        param.onFinish = onFinish;
2353        param.interactive = interactiveCallback;
2354        return;
2355      }
2356    }
2357    let params: AnimateCallback = {
2358      timeout: timeout,
2359      start: startCallback,
2360      finish: endCallback,
2361      onFinish: onFinish,
2362      interactive: interactiveCallback
2363    };
2364    customTransitionMap.set(name, params);
2365  }
2366
2367  getAnimationId() {
2368    return Date.now();
2369  }
2370
2371  unRegisterNavParam(name: string): void {
2372    customTransitionMap.delete(name);
2373  }
2374
2375  fireInteractiveAnimation(id: string, operation: NavigationOperation) {
2376    let animation = customTransitionMap.get(id)?.interactive;
2377    if (!animation) {
2378      return;
2379    }
2380    animation(operation);
2381  }
2382
2383  updateProgress(progress: number) {
2384    if (!this.proxy?.updateTransition) {
2385      return;
2386    }
2387    progress = this.operation == NavigationOperation.PUSH ? 1 - progress : progress;
2388    this.proxy?.updateTransition(progress);
2389  }
2390
2391  cancelTransition() {
2392    if (this.proxy?.cancelTransition) {
2393      this.proxy.cancelTransition();
2394    }
2395  }
2396
2397  recoverState() {
2398    if (!this.proxy?.from.navDestinationId || !this.proxy?.to.navDestinationId) {
2399      return;
2400    }
2401    let fromParam = customTransitionMap.get(this.proxy.from.navDestinationId);
2402    if (fromParam?.onFinish) {
2403      fromParam.onFinish(false, false);
2404    }
2405    let toParam = customTransitionMap.get(this.proxy?.to.navDestinationId);
2406    if (toParam?.onFinish) {
2407      toParam.onFinish(true, true);
2408    }
2409  }
2410
2411  finishTransition() {
2412    this.proxy?.finishTransition();
2413  }
2414
2415  finishInteractiveAnimation(rate: number) {
2416    if (this.operation == NavigationOperation.PUSH) {
2417      if (rate > 0.5) {
2418        if (this.proxy?.cancelTransition) {
2419          this.proxy.cancelTransition();
2420        }
2421      } else {
2422        this.proxy?.finishTransition();
2423      }
2424    } else {
2425      if (rate > 0.5) {
2426        this.proxy?.finishTransition();
2427      } else {
2428        if (this.proxy?.cancelTransition) {
2429          this.proxy.cancelTransition();
2430        }
2431      }
2432    }
2433  }
2434
2435  getAnimateParam(name: string): AnimateCallback {
2436    let result: AnimateCallback = {
2437      start: customTransitionMap.get(name)?.start,
2438      finish: customTransitionMap.get(name)?.finish,
2439      timeout: customTransitionMap.get(name)?.timeout,
2440      onFinish: customTransitionMap.get(name)?.onFinish,
2441      interactive: customTransitionMap.get(name)?.interactive,
2442    };
2443    return result;
2444  }
2445}
2446```
2447```json
2448// Configure {"routerMap": "$profile:route_map"} in the project configuration file module.json5.
2449// route_map.json
2450{
2451  "routerMap": [
2452    {
2453      "name": "pageOne",
2454      "pageSourceFile": "src/main/ets/pages/PageOne.ets",
2455      "buildFunction": "PageOneBuilder",
2456      "data": {
2457        "description": "this is pageOne"
2458      }
2459    },
2460    {
2461      "name": "pageTwo",
2462      "pageSourceFile": "src/main/ets/pages/PageTwo.ets",
2463      "buildFunction": "PageTwoBuilder"
2464    }
2465  ]
2466}
2467```
2468![navigation_interactive_transition](figures/navigation_interactive_transition.gif)
2469
2470### Example 4: Implementing a Navigation Component with Parameter Returning
2471
2472This example demonstrates how to use the APIs in **NavPathStack** to pass parameters back to the previous page.
2473
2474```ts
2475// Index.ets
2476
2477@Entry
2478@Component
2479struct NavigationExample {
2480  pageInfo: NavPathStack = new NavPathStack()
2481
2482  build() {
2483    Navigation(this.pageInfo) {
2484      Column() {
2485        Button('StartTest', { stateEffect: true, type: ButtonType.Capsule })
2486          .width('80%')
2487          .height(40)
2488          .margin(20)
2489          .onClick(() => {
2490            this.pageInfo.pushPath({ name: 'pageOne' }); // Push the navigation destination page specified by name to the navigation stack.
2491          })
2492      }
2493    }.title('NavIndex')
2494  }
2495}
2496```
2497```ts
2498// PageOne.ets
2499import { BusinessError } from '@kit.BasicServicesKit';
2500
2501class TmpClass {
2502  count: number = 10
2503}
2504
2505class ParamWithOp {
2506  operation: number = 1
2507  count: number = 10
2508}
2509
2510@Builder
2511export function PageOneBuilder(name: string, param: Object) {
2512  PageOne()
2513}
2514
2515@Component
2516export struct PageOne {
2517  pageInfo: NavPathStack = new NavPathStack();
2518  @State message: string = 'Hello World'
2519
2520  build() {
2521    NavDestination() {
2522      Column() {
2523        Text(this.message)
2524          .width('80%')
2525          .height(50)
2526          .margin(10)
2527
2528        Button('pushPath', { stateEffect: true, type: ButtonType.Capsule })
2529          .width('80%')
2530          .height(40)
2531          .margin(10)
2532          .onClick(() => {
2533            this.pageInfo.pushPath({
2534              name: 'pageTwo', param: new ParamWithOp(), onPop: (popInfo: PopInfo) => {
2535                this.message =
2536                  '[pushPath]last page is: ' + popInfo.info.name + ', result: ' + JSON.stringify(popInfo.result);
2537              }
2538            }); // Push the navigation destination page specified by name, with the data specified by param, to the navigation stack. Use the onPop callback to receive the page processing result.
2539          })
2540
2541        Button('pushPathByName', { stateEffect: true, type: ButtonType.Capsule })
2542          .width('80%')
2543          .height(40)
2544          .margin(10)
2545          .onClick(() => {
2546            let tmp = new TmpClass()
2547            this.pageInfo.pushPathByName('pageTwo', tmp, (popInfo) => {
2548              this.message =
2549                '[pushPathByName]last page is: ' + popInfo.info.name + ', result: ' + JSON.stringify(popInfo.result);
2550            }); // Push the navigation destination page specified by name, with the data specified by param, to the navigation stack. Use the onPop callback to receive the page processing result.
2551          })
2552
2553        Button('pushDestination', { stateEffect: true, type: ButtonType.Capsule })
2554          .width('80%')
2555          .height(40)
2556          .margin(10)
2557          .onClick(() => {
2558            let tmp = new TmpClass()
2559            // Push the navigation destination page specified by name, with the data specified by param, to the navigation stack. Use the onPop callback to receive the page processing result.
2560            this.pageInfo.pushDestination({
2561              name: 'pageTwo', param: new ParamWithOp(), onPop: (popInfo: PopInfo) => {
2562                this.message =
2563                  '[pushDestination]last page is: ' + popInfo.info.name + ', result: ' + JSON.stringify(popInfo.result);
2564              }
2565            }).catch((error: BusinessError) => {
2566              console.error(`[pushDestination]failed, error code = ${error.code}, error.message = ${error.message}.`);
2567            }).then(() => {
2568              console.error('[pushDestination]success.');
2569            });
2570          })
2571
2572        Button('pushDestinationByName', { stateEffect: true, type: ButtonType.Capsule })
2573          .width('80%')
2574          .height(40)
2575          .margin(10)
2576          .onClick(() => {
2577            let tmp = new TmpClass()
2578            // Push the navigation destination page specified by name, with the data specified by param, to the navigation stack. Use the onPop callback to receive the page processing result.
2579            this.pageInfo.pushDestinationByName('pageTwo', tmp, (popInfo) => {
2580              this.message = '[pushDestinationByName]last page is: ' + popInfo.info.name + ', result: ' +
2581              JSON.stringify(popInfo.result);
2582            }).catch((error: BusinessError) => {
2583              console.error(`[pushDestinationByName]failed, error code = ${error.code}, error.message = ${error.message}.`);
2584            }).then(() => {
2585              console.error('[pushDestinationByName]success.');
2586            });
2587          })
2588
2589        Button('pushPathWithoutOnPop', { stateEffect: true, type: ButtonType.Capsule })
2590          .width('80%')
2591          .height(40)
2592          .margin(10)
2593          .onClick(() => {
2594            this.pageInfo.pushPath({ name: 'pageTwo', param: new ParamWithOp() }); // Push the navigation destination page specified by name to the navigation stack.
2595          })
2596
2597        Button('pushPathByNameWithoutOnPop', { stateEffect: true, type: ButtonType.Capsule })
2598          .width('80%')
2599          .height(40)
2600          .margin(10)
2601          .onClick(() => {
2602            let tmp = new TmpClass()
2603            this.pageInfo.pushPathByName('pageTwo', tmp); // Push the navigation destination page specified by name, with the data specified by param, to the navigation stack.
2604          })
2605
2606        Button('pushDestinationWithoutOnPop', { stateEffect: true, type: ButtonType.Capsule })
2607          .width('80%')
2608          .height(40)
2609          .margin(10)
2610          .onClick(() => {
2611            let tmp = new TmpClass()
2612            // Push the navigation destination page specified by name, with the data specified by param, to the navigation stack. Use the onPop callback to receive the page processing result.
2613            this.pageInfo.pushDestination({ name: 'pageTwo', param: new ParamWithOp() })
2614              .catch((error: BusinessError) => {
2615                console.error(`[pushDestinationWithoutOnPop]failed, error code = ${error.code}, error.message = ${error.message}.`);
2616              }).then(() => {
2617              console.error('[pushDestinationWithoutOnPop]success.');
2618            });
2619          })
2620
2621        Button('pushDestinationByNameWithoutOnPop', { stateEffect: true, type: ButtonType.Capsule })
2622          .width('80%')
2623          .height(40)
2624          .margin(10)
2625          .onClick(() => {
2626            let tmp = new TmpClass()
2627            // Push the navigation destination page specified by name, with the data specified by param, to the navigation stack.
2628            this.pageInfo.pushDestinationByName('pageTwo', tmp)
2629              .catch((error: BusinessError) => {
2630                console.error(`[pushDestinationByNameWithoutOnPop]failed, error code = ${error.code}, error.message = ${error.message}.`);
2631              }).then(() => {
2632              console.error('[pushDestinationByNameWithoutOnPop]success.');
2633            });
2634          })
2635
2636        Button('clear', { stateEffect: true, type: ButtonType.Capsule })
2637          .width('80%')
2638          .height(40)
2639          .margin(10)
2640          .onClick(() => {
2641            this.pageInfo.clear(); // Clear the navigation stack.
2642          })
2643      }.width('100%').height('100%')
2644    }.title('pageOne')
2645    .onBackPressed(() => {
2646      this.pageInfo.pop({ number: 1 }) // Pop the top element out of the navigation stack.
2647      return true
2648    }).onReady((context: NavDestinationContext) => {
2649      this.pageInfo = context.pathStack;
2650    })
2651  }
2652}
2653```
2654```ts
2655// PageTwo.ets
2656
2657class resultClass {
2658  constructor(count: number) {
2659    this.count = count;
2660  }
2661
2662  count: number = 10
2663}
2664
2665@Builder
2666export function PageTwoBuilder() {
2667  PageTwo()
2668}
2669
2670@Component
2671export struct PageTwo {
2672  pathStack: NavPathStack = new NavPathStack()
2673
2674  build() {
2675    NavDestination() {
2676      Column() {
2677        Button('pop', { stateEffect: true, type: ButtonType.Capsule })
2678          .width('80%')
2679          .height(40)
2680          .margin(20)
2681          .onClick(() => {
2682            this.pathStack.pop(new resultClass(1)); // Return to the previous page and pass in the processing result to the onPop callback of push.
2683          })
2684
2685        Button('popToName', { stateEffect: true, type: ButtonType.Capsule })
2686          .width('80%')
2687          .height(40)
2688          .margin(20)
2689          .onClick(() => {
2690            this.pathStack.popToName('pageOne',
2691              new resultClass(11)); // Move the first navigation destination page that matches name to the top of the navigation stack, and pass in the processing result to the onPop callback of push.
2692          })
2693
2694        Button('popToIndex', { stateEffect: true, type: ButtonType.Capsule })
2695          .width('80%')
2696          .height(40)
2697          .margin(20)
2698          .onClick(() => {
2699            this.pathStack.popToIndex(0, new resultClass(111)); // Move the navigation destination page specified by index to the top of the navigation stack, and pass in the processing result to the onPop callback of push.
2700          })
2701
2702        Button('popWithoutResult', { stateEffect: true, type: ButtonType.Capsule })
2703          .width('80%')
2704          .height(40)
2705          .margin(20)
2706          .onClick(() => {
2707            this.pathStack.pop();
2708          })
2709
2710        Button('popToNameWithoutResult', { stateEffect: true, type: ButtonType.Capsule })
2711          .width('80%')
2712          .height(40)
2713          .margin(20)
2714          .onClick(() => {
2715            this.pathStack.popToName('pageOne');
2716          })
2717
2718        Button('popToIndexWithoutResult', { stateEffect: true, type: ButtonType.Capsule })
2719          .width('80%')
2720          .height(40)
2721          .margin(20)
2722          .onClick(() => {
2723            this.pathStack.popToIndex(0);
2724          })
2725      }.width('100%').height('100%')
2726    }.title('pageTwo')
2727    .onBackPressed(() => {
2728      this.pathStack.pop(new resultClass(0)); // Return to the previous page and pass in the processing result to the onPop callback of push.
2729      return true;
2730    }).onReady((context: NavDestinationContext) => {
2731      this.pathStack = context.pathStack
2732    })
2733  }
2734}
2735```
2736```json
2737// Configure {"routerMap": "$profile:route_map"} in the project configuration file module.json5.
2738// route_map.json
2739{
2740  "routerMap": [
2741    {
2742      "name": "pageOne",
2743      "pageSourceFile": "src/main/ets/pages/PageOne.ets",
2744      "buildFunction": "PageOneBuilder",
2745      "data": {
2746        "description": "this is pageOne"
2747      }
2748    },
2749    {
2750      "name": "pageTwo",
2751      "pageSourceFile": "src/main/ets/pages/PageTwo.ets",
2752      "buildFunction": "PageTwoBuilder"
2753    }
2754  ]
2755}
2756```
2757![navigationWithOnPop.gif](figures/navigationWithOnPop.gif)
2758
2759### Example 5: Setting the Background Color and Blur Effect
2760
2761This example demonstrates how to set the background color and background blur effect for the title bar of the home page in **Navigation**, as well as for the toolbar and the title bars on the **NavDestination** pages.
2762
2763```ts
2764let COLOR1: string = "#80004AAF";
2765let COLOR2: string = "#802787D9";
2766let BLUR_STYLE_1: BlurStyle = BlurStyle.BACKGROUND_THIN;
2767let BLUR_STYLE_2: BlurStyle = BlurStyle.BACKGROUND_THICK;
2768
2769@Component
2770struct BackComponent {
2771  build() {
2772    Row() {
2773      Column() {
2774      }
2775      .height('100%')
2776      .backgroundColor("#3D9DB4")
2777      .layoutWeight(9)
2778
2779      Column() {
2780      }
2781      .height('100%')
2782      .backgroundColor("#17A98D")
2783      .layoutWeight(9)
2784
2785      Column() {
2786      }
2787      .height('100%')
2788      .backgroundColor("#FFC000")
2789      .layoutWeight(9)
2790    }
2791    .height('100%')
2792    .width('100%')
2793  }
2794}
2795
2796@Component
2797struct ColorAndBlur {
2798  @State useColor1: boolean = true;
2799  @State useBlur1: boolean = true;
2800
2801  build() {
2802    NavDestination() {
2803      Stack({ alignContent: Alignment.Center }) {
2804        BackComponent()
2805          .width('100%')
2806          .height('100%')
2807        Column() {
2808          Stack({ alignContent: Alignment.Center }) {
2809            Button("switch color")
2810              .onClick(() => {
2811                this.useColor1 = !this.useColor1;
2812              })
2813          }
2814          .width('100%')
2815          .layoutWeight(1)
2816
2817          Stack({ alignContent: Alignment.Center }) {
2818            Button("switch blur")
2819              .onClick(() => {
2820                this.useBlur1 = !this.useBlur1;
2821              })
2822          }
2823          .width('100%')
2824          .layoutWeight(1)
2825        }
2826        .width('100%')
2827        .height('100%')
2828      }.width('100%')
2829      .height('100%')
2830    }
2831    .width('100%')
2832    .height('100%')
2833    // You can set the background color and background blur style of the title bar.
2834    .title("switch titlebar color and blur", {
2835      backgroundColor: this.useColor1 ? COLOR1 : COLOR2,
2836      backgroundBlurStyle: this.useBlur1 ? BLUR_STYLE_1 : BLUR_STYLE_2,
2837      barStyle: BarStyle.STACK
2838    })
2839  }
2840}
2841
2842@Entry
2843@Component
2844struct Index {
2845  private stack: NavPathStack = new NavPathStack();
2846  @State useColor1: boolean = true;
2847  @State useBlur1: boolean = true;
2848
2849  @Builder
2850  PageBuilder(name: string) {
2851    ColorAndBlur()
2852  }
2853
2854  build() {
2855    Navigation(this.stack) {
2856      Stack({ alignContent: Alignment.Center }) {
2857        BackComponent()
2858          .width('100%')
2859          .height('100%')
2860        Column() {
2861          Stack({ alignContent: Alignment.Center }) {
2862            Button("switch color")
2863              .onClick(() => {
2864                this.useColor1 = !this.useColor1;
2865              })
2866          }
2867          .width('100%')
2868          .layoutWeight(1)
2869
2870          Stack({ alignContent: Alignment.Center }) {
2871            Button("switch blur")
2872              .onClick(() => {
2873                this.useBlur1 = !this.useBlur1;
2874              })
2875          }
2876          .width('100%')
2877          .layoutWeight(1)
2878
2879          Stack({ alignContent: Alignment.Center }) {
2880            Button("push page")
2881              .onClick(() => {
2882                this.stack.pushPath({ name: "page" })
2883              })
2884          }
2885          .width('100%')
2886          .layoutWeight(1)
2887        }
2888        .width('100%')
2889        .height('80%')
2890      }.width('100%')
2891      .height('100%')
2892    }
2893    .width('100%')
2894    .height('100%')
2895    .navDestination(this.PageBuilder)
2896    // You can set the background color and background blur style of the title bar.
2897    .title("NavTitle", {
2898      backgroundColor: this.useColor1 ? COLOR1 : COLOR2,
2899      backgroundBlurStyle: this.useBlur1 ? BLUR_STYLE_1 : BLUR_STYLE_2,
2900      barStyle: BarStyle.STACK
2901    })
2902    // You can set the background color and background blur style of the toolbar.
2903    .toolbarConfiguration([
2904      { value: "a" },
2905      { value: "b" },
2906      { value: "c" }
2907    ], {
2908      backgroundColor: this.useColor1 ? COLOR1 : COLOR2,
2909      backgroundBlurStyle: this.useBlur1 ? BLUR_STYLE_1 : BLUR_STYLE_2
2910    })
2911  }
2912}
2913```
2914![navigationColorBlur.gif](figures/navigationColorBlur.gif)
2915
2916### Example 6: Obtaining the Outer Stack for a Nested Navigation Component
2917
2918This example shows how to obtain the parent **NavPathStack** for a nested **Navigation** component.
2919
2920```ts
2921@Entry
2922@Component
2923struct NavigationExample1 {
2924  @State childNavStack: NavPathStack = new NavPathStack();
2925
2926  build() {
2927    Navigation() {
2928      Stack({ alignContent: Alignment.Center }) {
2929        Navigation(this.childNavStack) {
2930          Button('push Path to parent Navigation', { stateEffect: true, type: ButtonType.Capsule })
2931            .width('80%')
2932            .height(40)
2933            .margin(20)
2934            .onClick(() => {
2935              // The parent the parent navigation path stack can be obtained.
2936              let parentStack = this.childNavStack.getParent();
2937              parentStack?.pushPath({ name: "pageOne" })
2938            })
2939        }
2940        .clip(true)
2941        .backgroundColor(Color.Orange)
2942        .width('80%')
2943        .height('80%')
2944        .title('ChildNavigation')
2945      }
2946      .width('100%')
2947      .height('100%')
2948    }
2949    .backgroundColor(Color.Green)
2950    .width('100%')
2951    .height('100%')
2952    .title('ParentNavigation')
2953  }
2954}
2955```
2956```ts
2957// PageOne.ets
2958  @Builder
2959  export function PageOneBuilder(name: string) {
2960    NavDestination() {
2961      Text("this is " + name)
2962    }
2963    .title(name)
2964  }
2965```
2966```json
2967// Configure {"routerMap": "$profile:route_map"} in the project configuration file module.json5.
2968// route_map.json
2969{
2970  "routerMap": [
2971    {
2972      "name": "pageOne",
2973      "pageSourceFile": "src/main/ets/pages/PageOne.ets",
2974      "buildFunction": "PageOneBuilder",
2975      "data": {
2976        "description": "this is pageOne"
2977      }
2978    }
2979  ]
2980}
2981```
2982![navPathStackGetParent.gif](figures/navPathStackGetParent.gif)
2983
2984### Example 7: Obtaining the Stack Through onReady
2985
2986This example demonstrates the following:
2987
29881. The navigation stack operation can be conducted even when **NavPathStack** is not declared as a state variable.
2989
29902. The **NavDestination** can obtain the corresponding **NavPathInfo** and **NavPathStack** through the **onReady** event.
2991
2992```ts
2993class PageParam {
2994  constructor(num_: number) {
2995    this.num = num_;
2996  }
2997
2998  num: number = 0;
2999}
3000
3001@Builder
3002export function PageOneBuilder(name: string, param: Object) {
3003  PageOne()
3004}
3005
3006@Component
3007struct PageOne {
3008  private stack: NavPathStack | null = null;
3009  private name: string = "";
3010  private paramNum: number = 0;
3011
3012  build() {
3013    NavDestination() {
3014      Column() {
3015        Text("NavPathInfo: name: " + this.name + ", paramNum: " + this.paramNum)
3016        Button('pushPath', { stateEffect: true, type: ButtonType.Capsule })
3017          .width('80%')
3018          .height(40)
3019          .margin(20)
3020          .onClick(() => {
3021            if (this.stack) {
3022              let p = new PageParam(this.paramNum + 1);
3023              this.stack.pushPath({ name: "pageOne", param: p });
3024            }
3025          })
3026        Button('pop', { stateEffect: true, type: ButtonType.Capsule })
3027          .width('80%')
3028          .height(40)
3029          .margin(20)
3030          .onClick(() => {
3031            this.stack?.pop()
3032          })
3033      }
3034      .width('100%')
3035      .height('100%')
3036    }
3037    .title('pageOne')
3038    .onReady((ctx: NavDestinationContext) => {
3039      // The passed NavPathInfo and the owning NavPathStack objects can be obtained for <NavDestination>.
3040      try {
3041        this.name = ctx?.pathInfo?.name;
3042        this.paramNum = (ctx?.pathInfo?.param as PageParam)?.num;
3043        this.stack = ctx.pathStack;
3044      } catch (e) {
3045        console.log(`testTag onReady catch exception: ${JSON.stringify(e)}`)
3046      }
3047    })
3048  }
3049}
3050
3051@Entry
3052@Component
3053struct NavigationExample2 {
3054  private stack: NavPathStack = new NavPathStack();
3055
3056  build() {
3057    Navigation(this.stack) {
3058      Stack({ alignContent: Alignment.Center }) {
3059        Button('pushPath', { stateEffect: true, type: ButtonType.Capsule })
3060          .width('80%')
3061          .height(40)
3062          .margin(20)
3063          .onClick(() => {
3064            let p = new PageParam(1);
3065            this.stack.pushPath({ name: "pageOne", param: p })
3066          })
3067      }
3068      .width('100%')
3069      .height('100%')
3070    }
3071    .width('100%')
3072    .height('100%')
3073    .title('Navigation')
3074  }
3075}
3076```
3077```json
3078// Configure {"routerMap": "$profile:route_map"} in the project configuration file module.json5.
3079// route_map.json
3080{
3081  "routerMap": [
3082    {
3083      "name": "pageOne",
3084      "pageSourceFile": "src/main/ets/pages/Index.ets",
3085      "buildFunction": "PageOneBuilder",
3086      "data": {
3087        "description": "this is pageOne"
3088      }
3089    }
3090  ]
3091}
3092```
3093![navigationOnReady1.gif](figures/navigationOnReady1.gif)
3094
3095### Example 8: Using NavDestination Lifecycle Callbacks
3096
3097This example demonstrates the timing of the **NavDestination** component lifecycle callbacks: **onAppear**, **onDisappear**, **onShown**, **onHidden**, **onWillAppear**, **onWillDisappear**, **onWillShow**, and **onWillHide**.
3098
3099```ts
3100@Builder
3101export function PageOneBuilder(name: string, param: Object) {
3102  PageOneComponent()
3103}
3104
3105@Component
3106struct PageOneComponent {
3107  private stack: NavPathStack | null = null;
3108  @State eventStr: string = "";
3109
3110  build() {
3111    NavDestination() {
3112      Column() {
3113        Text("event: " + this.eventStr)
3114        Button('pushPath', { stateEffect: true, type: ButtonType.Capsule })
3115          .width('80%')
3116          .height(40)
3117          .margin(20)
3118          .onClick(() => {
3119            if (this.stack) {
3120              this.stack.pushPath({ name: "pageOne" });
3121            }
3122          })
3123        Button('pop', { stateEffect: true, type: ButtonType.Capsule })
3124          .width('80%')
3125          .height(40)
3126          .margin(20)
3127          .onClick(() => {
3128            this.stack?.pop()
3129          })
3130      }
3131      .width('100%')
3132      .height('100%')
3133    }
3134    .title('pageOne')
3135    .onAppear(() => {
3136      this.eventStr += "<onAppear>";
3137    })
3138    .onDisAppear(() => {
3139      this.eventStr += "<onDisAppear>";
3140    })
3141    .onShown(() => {
3142      this.eventStr += "<onShown>";
3143    })
3144    .onHidden(() => {
3145      this.eventStr += "<onHidden>";
3146    })
3147    .onWillAppear(() => {
3148      this.eventStr += "<onWillAppear>";
3149    })
3150    .onWillDisappear(() => {
3151      this.eventStr += "<onWillDisappear>";
3152    })
3153    .onWillShow(() => {
3154      this.eventStr += "<onWillShow>";
3155    })
3156    .onWillHide(() => {
3157      this.eventStr += "<onWillHide>";
3158    })
3159    // onReady is called before onAppear.
3160    .onReady((ctx: NavDestinationContext) => {
3161      try {
3162        this.eventStr += "<onReady>";
3163        this.stack = ctx.pathStack;
3164      } catch (e) {
3165        console.log(`testTag onReady catch exception: ${JSON.stringify(e)}`)
3166      }
3167    })
3168  }
3169}
3170
3171@Entry
3172@Component
3173struct NavigationExample3 {
3174  private stack: NavPathStack = new NavPathStack();
3175
3176  build() {
3177    Navigation(this.stack) {
3178      Stack({ alignContent: Alignment.Center }) {
3179        Button('pushPath', { stateEffect: true, type: ButtonType.Capsule })
3180          .width('80%')
3181          .height(40)
3182          .margin(20)
3183          .onClick(() => {
3184            this.stack.pushPath({ name: "pageOne" })
3185          })
3186      }
3187      .width('100%')
3188      .height('100%')
3189    }
3190    .width('100%')
3191    .height('100%')
3192    .title('Navigation')
3193  }
3194}
3195```
3196```json
3197// Configure {"routerMap": "$profile:route_map"} in the project configuration file module.json5.
3198// route_map.json
3199{
3200  "routerMap": [
3201    {
3202      "name": "pageOne",
3203      "pageSourceFile": "src/main/ets/pages/Index.ets",
3204      "buildFunction": "PageOneBuilder",
3205      "data": {
3206        "description": "this is pageOne"
3207      }
3208    }
3209  ]
3210}
3211```
3212![navigationOnReady2.gif](figures/navigationOnReady2.gif)
3213
3214
3215### Example 9: Configuring the Title Bar Stack Layout
3216
3217This example demonstrates the stack layout of the title bar in the **Navigation** component.
3218
3219```ts
3220@Entry
3221@Component
3222struct NavigationExample {
3223  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
3224  private scrollerForScroll: Scroller = new Scroller();
3225  @State barStyle: BarStyle = BarStyle.STANDARD;
3226
3227  build() {
3228    Column() {
3229      Navigation() {
3230        Column() {
3231          Scroll(this.scrollerForScroll) {
3232            Column() {
3233              Image($r('app.media.image_1'))// Set the height to be the same as that of the title bar to observe the STACK effect.
3234                .height(138)
3235                .width('100%')
3236              Button('BarStyle.STANDARD')
3237                .height('50vp')
3238                .onClick(() => {
3239                  this.barStyle = BarStyle.STANDARD;
3240                })
3241              Button('BarStyle.STACK')
3242                .height('50vp')
3243                .margin({ top: 12 })
3244                .onClick(() => {
3245                  this.barStyle = BarStyle.STACK;
3246                })
3247
3248              ForEach(this.arr, (item: number) => {
3249                ListItem() {
3250                  Text('' + item)
3251                    .width('100%')
3252                    .height(100)
3253                    .fontSize(16)
3254                    .textAlign(TextAlign.Center)
3255                    .borderRadius(10)
3256                    .backgroundColor(Color.Orange)
3257                    .margin({ top: 12 })
3258                }
3259              }, (item: string) => item)
3260            }
3261          }
3262        }
3263        .width('100%')
3264        .height('100%')
3265        .backgroundColor(0xDCDCDC)
3266      }
3267      .title(
3268        {
3269          main: 'NavTitle',
3270          sub: 'subtitle'
3271        },
3272        {
3273          backgroundBlurStyle: BlurStyle.COMPONENT_THICK,
3274          barStyle: this.barStyle,
3275        }
3276      )
3277      .titleMode(NavigationTitleMode.Free)
3278      .hideTitleBar(false)
3279    }.width('100%').height('100%').backgroundColor('#F1F3F5')
3280  }
3281}
3282```
3283![titlebar_stack.gif](figures/titlebar_stack.gif)
3284
3285
3286### Example 10: Defining a Derived Class of NavPathStack
3287
3288This example demonstrates how to define a derived class of **NavPathStack** and the basic usage of the derived class in **Navigation**.
3289
3290```ts
3291class DerivedNavPathStack extends NavPathStack {
3292  // usr defined property 'id'
3293  id: string = "__default__"
3294
3295  // new function in derived class
3296  setId(id: string) {
3297    this.id = id;
3298  }
3299
3300  // new function in derived class
3301  getInfo(): string {
3302    return "this page used Derived NavPathStack, id: " + this.id
3303  }
3304
3305  // overwrite function of NavPathStack
3306  pushPath(info: NavPathInfo, animated?: boolean): void
3307  pushPath(info: NavPathInfo, options?: NavigationOptions): void
3308  pushPath(info: NavPathInfo, secArg?: boolean | NavigationOptions): void {
3309    console.log('[derive-test] reached DerivedNavPathStack\'s pushPath');
3310    if (typeof secArg === 'boolean') {
3311      super.pushPath(info, secArg);
3312    } else {
3313      super.pushPath(info, secArg);
3314    }
3315  }
3316
3317  // overwrite and overload function of NavPathStack
3318  pop(animated?: boolean | undefined): NavPathInfo | undefined
3319  pop(result: Object, animated?: boolean | undefined): NavPathInfo | undefined
3320  pop(result?: Object, animated?: boolean | undefined): NavPathInfo | undefined {
3321    console.log('[derive-test] reached DerivedNavPathStack\'s pop');
3322    return super.pop(result, animated);
3323  }
3324
3325  // other function of base class...
3326}
3327
3328class param {
3329  info: string = "__default_param__";
3330
3331  constructor(info: string) {
3332    this.info = info
3333  }
3334}
3335
3336@Entry
3337@Component
3338struct Index {
3339  derivedStack: DerivedNavPathStack = new DerivedNavPathStack();
3340
3341  aboutToAppear(): void {
3342    this.derivedStack.setId('origin stack');
3343  }
3344
3345  @Builder
3346  pageMap(name: string) {
3347    PageOne()
3348  }
3349
3350  build() {
3351    Navigation(this.derivedStack) {
3352      Button('to Page One').margin(20).onClick(() => {
3353        this.derivedStack.pushPath({
3354          name: 'pageOne',
3355          param: new param('push pageOne in homePage when stack size: ' + this.derivedStack.size())
3356        });
3357      })
3358    }.navDestination(this.pageMap)
3359    .title('Home Page')
3360  }
3361}
3362
3363@Component
3364struct PageOne {
3365  derivedStack: DerivedNavPathStack = new DerivedNavPathStack();
3366  curStringifyParam: string = "NA";
3367
3368  build() {
3369    NavDestination() {
3370      Column() {
3371        Text(this.derivedStack.getInfo())
3372          .margin(10)
3373          .fontSize(25)
3374          .fontWeight(FontWeight.Bold)
3375          .textAlign(TextAlign.Start)
3376        Text('current page param info:')
3377          .margin(10)
3378          .fontSize(25)
3379          .fontWeight(FontWeight.Bold)
3380          .textAlign(TextAlign.Start)
3381        Text(this.curStringifyParam)
3382          .margin(20)
3383          .fontSize(20)
3384          .textAlign(TextAlign.Start)
3385      }.backgroundColor(Color.Pink)
3386
3387      Button('to Page One').margin(20).onClick(() => {
3388        this.derivedStack.pushPath({
3389          name: 'pageOne',
3390          param: new param('push pageOne in pageOne when stack size: ' + this.derivedStack.size())
3391        });
3392      })
3393    }.title('Page One')
3394    .onReady((context: NavDestinationContext) => {
3395      console.log('[derive-test] reached PageOne\'s onReady');
3396      // get derived stack from navdestinationContext
3397      this.derivedStack = context.pathStack as DerivedNavPathStack;
3398      console.log('[derive-test] -- got derivedStack: ' + this.derivedStack.id);
3399      this.curStringifyParam = JSON.stringify(context.pathInfo.param);
3400      console.log('[derive-test] -- got param: ' + this.curStringifyParam);
3401    })
3402  }
3403}
3404```
3405![derive_stack.gif](figures/derive_stack.gif)
3406
3407### Example 11: Using Symbol Icons
3408
3409This example shows how to use symbol icons in **Navigation** and **NavDestination**.
3410
3411```ts
3412import { SymbolGlyphModifier } from '@kit.ArkUI';
3413
3414@Entry
3415@Component
3416struct NavigationExample {
3417  @Provide('navPathStack') navPathStack: NavPathStack = new NavPathStack();
3418  @State menuItems: Array<NavigationMenuItem> = [
3419    {
3420      value: 'menuItem1',
3421      icon: 'resources/base/media/ic_public_ok.svg' // Icon resource path.
3422    },
3423    {
3424      value: 'menuItem2',
3425      icon: 'resources/base/media/ic_public_ok.svg', // Icon resource path.
3426      symbolIcon: new SymbolGlyphModifier($r('sys.symbol.ohos_folder_badge_plus')).fontColor([Color.Red, Color.Green])
3427        .renderingStrategy(SymbolRenderingStrategy.MULTIPLE_COLOR),
3428    },
3429    {
3430      value: 'menuItem3',
3431      symbolIcon: new SymbolGlyphModifier($r('sys.symbol.ohos_lungs')),
3432    },
3433  ]
3434  @State toolItems: Array<ToolbarItem> = [
3435    {
3436      value: 'toolItem1',
3437      icon: 'resources/base/media/ic_public_ok.svg', // Icon resource path.
3438      symbolIcon: new SymbolGlyphModifier($r('sys.symbol.ohos_lungs')),
3439      status: ToolbarItemStatus.ACTIVE,
3440      activeSymbolIcon: new SymbolGlyphModifier($r('sys.symbol.ohos_folder_badge_plus')).fontColor([Color.Red,
3441        Color.Green]).renderingStrategy(SymbolRenderingStrategy.MULTIPLE_COLOR),
3442      action: () => {
3443      }
3444    },
3445    {
3446      value: 'toolItem2',
3447      symbolIcon: new SymbolGlyphModifier($r('sys.symbol.ohos_star')),
3448      status: ToolbarItemStatus.ACTIVE,
3449      activeIcon: 'resources/base/media/ic_public_more.svg', // Icon resource path.
3450      action: () => {
3451      }
3452    },
3453    {
3454      value: 'toolItem3',
3455      symbolIcon: new SymbolGlyphModifier($r('sys.symbol.ohos_star')),
3456      status: ToolbarItemStatus.ACTIVE,
3457      activeSymbolIcon: new SymbolGlyphModifier($r('sys.symbol.ohos_lungs')),
3458      action: () => {
3459      }
3460    }
3461  ]
3462
3463  @Builder
3464  myRouter(name: string, param?: Object) {
3465    if (name === 'NavigationMenu') {
3466      NavigationMenu();
3467    }
3468  }
3469
3470  build() {
3471    Navigation(this.navPathStack) {
3472      Column() {
3473        Button('Go').onClick(() => {
3474          this.navPathStack.pushPathByName('NavigationMenu', null);
3475        })
3476      }
3477    }
3478    .backButtonIcon(new SymbolGlyphModifier($r('sys.symbol.ohos_wifi')))
3479    .titleMode(NavigationTitleMode.Mini)
3480    .menus(this.menuItems)
3481    .toolbarConfiguration(this.toolItems)
3482    .title('Level-1 page')
3483    .navDestination(this.myRouter)
3484  }
3485}
3486
3487@Component
3488export struct NavigationMenu {
3489  @Consume('navPathStack') navPathStack: NavPathStack;
3490  @State menuItems: Array<NavigationMenuItem> = [
3491    {
3492      value: 'menuItem1',
3493      icon: 'resources/base/media/ic_public_ok.svg', // Icon resource path.
3494      action: () => {
3495      }
3496    },
3497    {
3498      value: 'menuItem2',
3499      symbolIcon: new SymbolGlyphModifier($r('sys.symbol.ohos_folder_badge_plus')).fontColor([Color.Red, Color.Green])
3500        .renderingStrategy(SymbolRenderingStrategy.MULTIPLE_COLOR),
3501      action: () => {
3502      }
3503    },
3504    {
3505      value: 'menuItem3',
3506      symbolIcon: new SymbolGlyphModifier($r('sys.symbol.repeat_1')),
3507      action: () => {
3508      }
3509    },
3510  ]
3511
3512  build() {
3513    NavDestination() {
3514      Row() {
3515        Column() {
3516        }
3517        .width('100%')
3518      }
3519      .height('100%')
3520    }
3521    .hideTitleBar(false)
3522    .title('NavDestination title')
3523    .backgroundColor($r('sys.color.ohos_id_color_titlebar_sub_bg'))
3524    .backButtonIcon(new SymbolGlyphModifier($r('sys.symbol.ohos_star')).fontColor([Color.Blue]))
3525    .menus(this.menuItems)
3526  }
3527}
3528```
3529![navigation_symbol.gif](figures/navigation_symbol.gif)
3530
3531### Example 12: Setting the Custom Title Bar Margin
3532
3533This example demonstrates how to set custom title bar padding in **Navigation** and **NavDestination**, and how to modify the main title and subtitle text styles through **TextModifier**.
3534
3535```ts
3536import { LengthMetrics } from '@kit.ArkUI';
3537import { TextModifier } from '@ohos.arkui.modifier';
3538
3539class MainTitleTextModfier extends TextModifier {
3540  useStyle1: boolean = true;
3541
3542  applyNormalAttribute(instance: TextModifier): void {
3543    if (this.useStyle1) {
3544      console.log(`testTag mainTitle use style1`);
3545      instance.fontColor('#FFFFC000')
3546      instance.fontSize(35)
3547      instance.fontWeight(FontWeight.Bolder)
3548      instance.fontStyle(FontStyle.Normal)
3549      instance.textShadow({ radius: 5, offsetX: 9 })
3550    } else {
3551      console.log(`testTag mainTitle use style2`);
3552      instance.fontColor('#FF23A98D')
3553      instance.fontSize(20)
3554      instance.heightAdaptivePolicy(TextHeightAdaptivePolicy.MIN_FONT_SIZE_FIRST)
3555      instance.fontWeight(FontWeight.Lighter)
3556      instance.fontStyle(FontStyle.Italic)
3557      instance.textShadow({ radius: 3, offsetX: 3 })
3558    }
3559  }
3560}
3561
3562class SubTitleTextModfier extends TextModifier {
3563  useStyle1: boolean = true;
3564
3565  applyNormalAttribute(instance: TextModifier): void {
3566    if (this.useStyle1) {
3567      console.log(`testTag subTitle use style1`);
3568      instance.fontColor('#FFFFC000')
3569      instance.fontSize(15)
3570      instance.fontWeight(FontWeight.Bolder)
3571      instance.fontStyle(FontStyle.Normal)
3572      instance.textShadow({ radius: 5, offsetX: 9 })
3573    } else {
3574      console.log(`testTag subTitle use style2`);
3575      instance.fontColor('#FF23A98D')
3576      instance.fontSize(10)
3577      instance.fontWeight(FontWeight.Lighter)
3578      instance.fontStyle(FontStyle.Italic)
3579      instance.textShadow({ radius: 3, offsetX: 3 })
3580    }
3581  }
3582}
3583
3584@Entry
3585@Component
3586struct NavigationExample {
3587  private navPathStack: NavPathStack = new NavPathStack();
3588  // Assign an initial padding at the start of the title bar.
3589  @State paddingStart: LengthMetrics = LengthMetrics.vp(0);
3590  // Assign an initial padding at the end of the title bar.
3591  @State paddingEnd: LengthMetrics = LengthMetrics.vp(0);
3592  // Main title attribute modifier.
3593  @State mainTitleModifier: MainTitleTextModfier = new MainTitleTextModfier();
3594  // Subtitle attribute modifier.
3595  @State subTitleModifier: SubTitleTextModfier = new SubTitleTextModfier();
3596  @State applyModifier: boolean = false;
3597  @State useStyle1: boolean = true;
3598
3599  @Builder
3600  myRouter(name: string, param?: Object) {
3601    if (name === 'NavDestinationExample') {
3602      NavDestinationExample();
3603    }
3604  }
3605
3606  build() {
3607    Navigation(this.navPathStack) {
3608      Column() {
3609        // Switch between padding values for the title bar.
3610        Button('apply padding 32vp')
3611          .onClick(() => {
3612            this.paddingStart = LengthMetrics.vp(32);
3613            this.paddingEnd = LengthMetrics.vp(32);
3614          })
3615          .margin({ top: 70 })
3616          .width(180)
3617        Button('apply padding 20vp')
3618          .onClick(() => {
3619            this.paddingStart = LengthMetrics.vp(20);
3620            this.paddingEnd = LengthMetrics.vp(20);
3621          })
3622          .margin({ top: 40 })
3623          .width(180)
3624        Button('pushPage')
3625          .onClick(() => {
3626            this.navPathStack.pushPath({ name: 'NavDestinationExample' })
3627          })
3628          .margin({ top: 40 })
3629          .width(180)
3630        Row() {
3631          Text(`apply Modifier`)
3632          Toggle({ isOn: this.applyModifier, type: ToggleType.Switch }).onChange((isOn: boolean) => {
3633            this.applyModifier = isOn;
3634          })
3635        }
3636        .padding({ top: 95, left: 5, right: 5 })
3637        .width(180)
3638        .justifyContent(FlexAlign.SpaceBetween)
3639
3640        Row() {
3641          Text(`use Style1`)
3642          Toggle({ isOn: this.useStyle1, type: ToggleType.Switch }).onChange((isOn: boolean) => {
3643            this.mainTitleModifier.useStyle1 = isOn;
3644            this.subTitleModifier.useStyle1 = isOn;
3645            this.useStyle1 = isOn;
3646          })
3647        }
3648        .padding({ top: 40, left: 5, right: 5 })
3649        .width(180)
3650        .justifyContent(FlexAlign.SpaceBetween)
3651      }
3652      .width('100%')
3653      .height('100%')
3654    }
3655    .titleMode(NavigationTitleMode.Full)
3656    .title(
3657      { main: "Title", sub: "subTitle" },
3658      this.applyModifier ?
3659        {
3660          paddingStart: this.paddingStart,
3661          paddingEnd: this.paddingEnd,
3662          mainTitleModifier: this.mainTitleModifier,
3663          subTitleModifier: this.subTitleModifier,
3664        } : {
3665        paddingStart: this.paddingStart,
3666        paddingEnd: this.paddingEnd
3667      })
3668    .navDestination(this.myRouter)
3669  }
3670}
3671
3672@Component
3673export struct NavDestinationExample {
3674  @State menuItems: Array<NavigationMenuItem> = [
3675    {
3676      value: 'menuItem1',
3677      icon: 'resources/base/media/ic_public_ok.svg', // Icon resource path.
3678      action: () => {
3679      }
3680    }
3681  ]
3682  @State paddingStart: LengthMetrics = LengthMetrics.vp(0);
3683  @State paddingEnd: LengthMetrics = LengthMetrics.vp(0);
3684  // Main title attribute modifier.
3685  @State mainTitleModifier: MainTitleTextModfier = new MainTitleTextModfier();
3686  // Subtitle attribute modifier.
3687  @State subTitleModifier: SubTitleTextModfier = new SubTitleTextModfier();
3688  @State applyModifier: boolean = false;
3689  @State useStyle1: boolean = true;
3690
3691  build() {
3692    NavDestination() {
3693      Column() {
3694        // Switch between padding values for the title bar.
3695        Button('apply padding 32vp')
3696          .onClick(() => {
3697            this.paddingStart = LengthMetrics.vp(32);
3698            this.paddingEnd = LengthMetrics.vp(32);
3699          })
3700          .margin({ top: 150 })
3701          .width(180)
3702        Button('apply padding 20vp')
3703          .onClick(() => {
3704            this.paddingStart = LengthMetrics.vp(20);
3705            this.paddingEnd = LengthMetrics.vp(20);
3706          })
3707          .margin({ top: 40 })
3708          .width(180)
3709        Row() {
3710          Text(`apply Modifier`)
3711          Toggle({ isOn: this.applyModifier, type: ToggleType.Switch }).onChange((isOn: boolean) => {
3712            this.applyModifier = isOn;
3713          })
3714        }
3715        .padding({ top: 95, left: 5, right: 5 })
3716        .width(180)
3717        .justifyContent(FlexAlign.SpaceBetween)
3718
3719        Row() {
3720          Text(`use Style1`)
3721          Toggle({ isOn: this.useStyle1, type: ToggleType.Switch }).onChange((isOn: boolean) => {
3722            this.mainTitleModifier.useStyle1 = isOn;
3723            this.subTitleModifier.useStyle1 = isOn;
3724            this.useStyle1 = isOn;
3725          })
3726        }
3727        .padding({ top: 40, left: 5, right: 5 })
3728        .width(180)
3729        .justifyContent(FlexAlign.SpaceBetween)
3730      }
3731      .width('100%')
3732      .height('90%')
3733    }
3734    .hideTitleBar(false)
3735    .title(
3736      { main: "Title", sub: "subTitle" },
3737      this.applyModifier ?
3738        {
3739          paddingStart: this.paddingStart,
3740          paddingEnd: this.paddingEnd,
3741          mainTitleModifier: this.mainTitleModifier,
3742          subTitleModifier: this.subTitleModifier,
3743        } : {
3744        paddingStart: this.paddingStart,
3745        paddingEnd: this.paddingEnd
3746      })
3747    .menus(this.menuItems)
3748  }
3749}
3750```
3751![titlebarPaddingAndModifier.gif](figures/titlebarPaddingAndModifier.gif)
3752
3753### Example 13: Implementing a Custom Transition Animation
3754
3755This example shows how to implement a custom transition animation for navigation between pages.
3756```ts
3757// Index.ets
3758import { AnimateCallback, CustomTransition } from './CustomTransitionUtils'
3759
3760@Entry
3761@Component
3762struct NavigationCustomTransitionExample {
3763  pageInfos: NavPathStack = new NavPathStack();
3764
3765  aboutToAppear() {
3766    this.pageInfos.pushPath({ name: 'PageOne' }, false);
3767  }
3768
3769  build() {
3770    Navigation(this.pageInfos) {
3771    }
3772    .hideNavBar(true)
3773    .customNavContentTransition((from: NavContentInfo, to: NavContentInfo, operation: NavigationOperation) => {
3774      // No custom animation for the home page
3775      if (from.index === -1 || to.index === -1) {
3776        return undefined;
3777      }
3778
3779      let customAnimation: NavigationAnimatedTransition = {
3780        timeout: 2000,
3781        // When the transition starts, the system calls this method and passes in the transition context proxy object.
3782        transition: (transitionProxy: NavigationTransitionProxy) => {
3783          if (!from.navDestinationId || !to.navDestinationId) {
3784            return;
3785          }
3786          // Obtain the corresponding transition animation callback from the CustomTransition class based on the sequence of subpages.
3787          let fromParam: AnimateCallback = CustomTransition.getInstance().getAnimateParam(from.navDestinationId);
3788          let toParam: AnimateCallback = CustomTransition.getInstance().getAnimateParam(to.navDestinationId);
3789          // Push animation
3790          if (operation == NavigationOperation.PUSH) {
3791            if (fromParam.start && toParam.start) {
3792              // Set the animation start for both pages in the push transition.
3793              fromParam.start(true, true);
3794              toParam.start(true, false);
3795            }
3796            animateTo({
3797              duration: 500, curve: Curve.Friction, onFinish: () => {
3798                // Manually call the finishTransition API after the animation ends. Otherwise, the system will automatically call the API after the specified timeout period.
3799                transitionProxy.finishTransition();
3800              }
3801            }, () => {
3802              if (fromParam.finish && toParam.finish) {
3803                // Set the animation end for both pages in the push transition.
3804                fromParam.finish(true, true);
3805                toParam.finish(true, false);
3806              }
3807
3808            })
3809          } else if (operation == NavigationOperation.POP) {
3810            // Pop animation
3811            if (fromParam.start && toParam.start) {
3812              // Set the animation start for both pages in the pop transition.
3813              fromParam.start(false, true);
3814              toParam.start(false, false);
3815            }
3816            animateTo({
3817              duration: 500, curve: Curve.Friction, onFinish: () => {
3818                // Manually call the finishTransition API after the animation ends. Otherwise, the system will automatically call the API after the specified timeout period.
3819                transitionProxy.finishTransition();
3820              }
3821            }, () => {
3822              if (fromParam.finish && toParam.finish) {
3823                // Set the animation end for both pages in the pop transition.
3824                fromParam.finish(false, true);
3825                toParam.finish(false, false);
3826              }
3827            })
3828          } else {
3829            // No animation for the replacement operation
3830          }
3831        }
3832      };
3833      return customAnimation;
3834    })
3835  }
3836}
3837
3838
3839// PageOne
3840@Builder
3841export function PageOneBuilder() {
3842  PageContainer({ title: "PageOne" })
3843}
3844
3845// PageTwo
3846@Builder
3847export function PageTwoBuilder() {
3848  PageContainer({ title: "PageTwo" })
3849}
3850
3851@Component
3852export struct PageContainer {
3853  pageInfos: NavPathStack = new NavPathStack();
3854  @State translateY: string = '0';
3855  pageId: string = '';
3856  title: string = ''
3857
3858  registerCallback() {
3859    CustomTransition.getInstance().registerNavParam(this.pageId,
3860      // Set the start point of the transition animation based on the transition type.
3861      (isPush: boolean, isExit: boolean) => {
3862        if (isPush) {
3863          if (isExit) {
3864            this.translateY = '0';
3865          } else {
3866            this.translateY = '100%';
3867          }
3868        } else {
3869          if (isExit) {
3870            this.translateY = '0';
3871          } else {
3872            this.translateY = '0';
3873          }
3874        }
3875      },
3876      // Set the end point of the transition animation based on the transition type.
3877      (isPush: boolean, isExit: boolean) => {
3878        if (isPush) {
3879          if (isExit) {
3880            this.translateY = '0';
3881          } else {
3882            this.translateY = '0';
3883          }
3884        } else {
3885          if (isExit) {
3886            this.translateY = '100%';
3887          } else {
3888            this.translateY = '0';
3889          }
3890        }
3891      });
3892  }
3893
3894  build() {
3895    NavDestination() {
3896      Column() {
3897        Button('push next page', { stateEffect: true, type: ButtonType.Capsule })
3898          .width('80%')
3899          .height(40)
3900          .margin(20)
3901          .onClick(() => {
3902            this.pageInfos.pushPath({ name: this.title == 'PageOne' ? "PageTwo" : "PageOne" })
3903          })
3904      }
3905      .size({ width: '100%', height: '100%' })
3906    }
3907    .title(this.title)
3908    .onDisAppear(() => {
3909      // Unregister the custom transition animation parameters when the page is destroyed.
3910      CustomTransition.getInstance().unRegisterNavParam(this.pageId);
3911    })
3912    .onReady((context: NavDestinationContext) => {
3913      this.pageInfos = context.pathStack;
3914      if (context.navDestinationId) {
3915        this.pageId = context.navDestinationId;
3916        // Register the custom transition animation parameters when the page is created.
3917        this.registerCallback();
3918      }
3919    })
3920    .translate({ y: this.translateY })
3921    .backgroundColor(this.title == 'PageOne' ? '#F1F3F5' : '#ff11dee5')
3922  }
3923}
3924```
3925```ts
3926// The CustomNavigationUtils.ts file defines a utility class for managing custom animation parameters for different pages.
3927
3928// Custom API to save the transition animation callback and parameters related to a page.
3929export interface AnimateCallback {
3930  start: ((isPush: boolean, isExit: boolean) => void | undefined) | undefined;
3931  finish: ((isPush: boolean, isExit: boolean) => void | undefined) | undefined
3932}
3933
3934const customTransitionMap: Map<string, AnimateCallback> = new Map();
3935
3936export class CustomTransition {
3937  static delegate = new CustomTransition();
3938
3939  static getInstance() {
3940    return CustomTransition.delegate;
3941  }
3942
3943  /* Register animation callbacks for a page.
3944   * name: unique ID of the target page
3945   * startCallback: used to set the page state at the start of the animation.
3946   * endCallback: used to set the page state at the end of the animation.
3947   */
3948  registerNavParam(name: string, startCallback: (isPush: boolean, isExit: boolean) => void,
3949    endCallback: (isPush: boolean, isExit: boolean) => void): void {
3950    if (customTransitionMap.has(name)) {
3951      let param = customTransitionMap.get(name);
3952      if (param != undefined) {
3953        param.start = startCallback;
3954        param.finish = endCallback;
3955        return;
3956      }
3957    }
3958    let params: AnimateCallback = { start: startCallback, finish: endCallback };
3959    customTransitionMap.set(name, params);
3960  }
3961
3962  unRegisterNavParam(name: string): void {
3963    customTransitionMap.delete(name);
3964  }
3965
3966  getAnimateParam(name: string): AnimateCallback {
3967    let result: AnimateCallback = {
3968      start: customTransitionMap.get(name)?.start,
3969      finish: customTransitionMap.get(name)?.finish
3970    };
3971    return result;
3972  }
3973}
3974```
3975
3976```json
3977// Configure {"routerMap": "$profile:route_map"} in the project configuration file module.json5.
3978// route_map.json
3979{
3980  "routerMap": [
3981    {
3982      "name": "PageOne",
3983      "pageSourceFile": "src/main/ets/pages/Index.ets",
3984      "buildFunction": "PageOneBuilder",
3985      "data": {
3986        "description": "this is pageOne"
3987      }
3988    },
3989    {
3990      "name": "PageTwo",
3991      "pageSourceFile": "src/main/ets/pages/Index.ets",
3992      "buildFunction": "PageTwoBuilder"
3993    }
3994  ]
3995}
3996```
3997![navigationCustomTransition.gif](figures/navigationCustomTransition.gif)
3998