1# Navigation 2 3Navigation组件是路由导航的根视图容器,一般作为Page页面的根容器使用,其内部默认包含了标题栏、内容区和工具栏,其中内容区默认首页显示导航内容(Navigation的子组件)或非首页显示([NavDestination](ts-basic-components-navdestination.md)的子组件),首页和非首页通过路由进行切换。 4 5> **说明:** 6> 7> 该组件从API Version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 8> 9> 该组件从API Version 11开始默认支持安全区避让特性(默认值为:expandSafeArea([SafeAreaType.SYSTEM, SafeAreaType.KEYBOARD, SafeAreaType.CUTOUT], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])),开发者可以重写该属性覆盖默认行为,API Version 11之前的版本需配合[expandSafeArea](ts-universal-attributes-expand-safe-area.md)属性实现安全区避让。 10 11 12## 子组件 13 14可以包含子组件。 15 16从API Version 9开始,推荐与[NavRouter](ts-basic-components-navrouter.md)组件搭配使用。 17 18从API Version 10开始,推荐使用[NavPathStack](#navpathstack10)配合navDestination属性进行页面路由。 19 20## 接口 21 22### Navigation 23 24Navigation() 25 26**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 27 28**系统能力:** SystemCapability.ArkUI.ArkUI.Full 29 30### Navigation<sup>10+</sup> 31 32Navigation(pathInfos: NavPathStack) 33 34绑定路由栈到Navigation组件。 35 36**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 37 38**系统能力:** SystemCapability.ArkUI.ArkUI.Full 39 40**参数:** 41 42| 参数名 | 类型 | 必填 | 说明 | 43| --------- | ------------------------------- | ---- | ------ | 44| pathInfos | [NavPathStack](#navpathstack10) | 是 | 路由栈信息。 | 45 46## 属性 47 48除支持[通用属性](ts-universal-attributes-size.md)外,还支持以下属性: 49 50### title 51 52title(value: ResourceStr | CustomBuilder | NavigationCommonTitle | NavigationCustomTitle, options?: NavigationTitleOptions) 53 54设置页面标题。 55 56**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 57 58**系统能力:** SystemCapability.ArkUI.ArkUI.Full 59 60**参数:** 61 62| 参数名 | 类型 | 必填 | 说明 | 63| ------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | 64| value | [ResourceStr](ts-types.md#resourcestr)<sup>10+</sup> \| [CustomBuilder](ts-types.md#custombuilder8) \| [NavigationCommonTitle](#navigationcommontitle9)<sup>9+</sup> \| [NavigationCustomTitle](#navigationcustomtitle9)<sup>9+</sup> | 是 | 页面标题,使用NavigationCustomTitle类型设置height高度时,[titleMode](#titlemode)属性不会生效。字符串超长时,如果不设置副标题,先缩小再换行(2行)最后...截断。如果设置副标题,先缩小最后...截断。 | 65| options | [NavigationTitleOptions](#navigationtitleoptions11)<sup>11+</sup> | 否 | 标题栏选项。 | 66 67### subTitle<sup>(deprecated)</sup> 68 69subTitle(value: string) 70 71设置页面副标题。 72 73从API Version 9开始废弃,建议使用[title](#title)代替。 74 75**系统能力:** SystemCapability.ArkUI.ArkUI.Full 76 77**参数:** 78 79| 参数名 | 类型 | 必填 | 说明 | 80| ------ | ------ | ---- | ------------ | 81| value | string | 是 | 页面副标题。 | 82 83### menus 84 85menus(value: Array<NavigationMenuItem> | CustomBuilder) 86 87> **说明:** 88> 89> 不支持通过SymbolGlyphModifier对象的fontSize属性修改图标大小、effectStrategy属性修改动效、symbolEffect属性修改动效类型。 90 91 92设置页面右上角菜单。不设置时不显示菜单项。使用Array<[NavigationMenuItem](#navigationmenuitem)> 写法时,竖屏最多支持显示3个图标,横屏最多支持显示5个图标,多余的图标会被放入自动生成的更多图标。 93 94**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 95 96**系统能力:** SystemCapability.ArkUI.ArkUI.Full 97 98**参数:** 99 100| 参数名 | 类型 | 必填 | 说明 | 101| ------ | ------------------------------------------------------------ | ---- | ---------------- | 102| value | Array<[NavigationMenuItem](#navigationmenuitem)> \| [CustomBuilder](ts-types.md#custombuilder8) | 是 | 页面右上角菜单。 | 103 104### titleMode 105 106titleMode(value: NavigationTitleMode) 107 108设置页面标题栏显示模式。 109 110**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 111 112**系统能力:** SystemCapability.ArkUI.ArkUI.Full 113 114**参数:** 115 116| 参数名 | 类型 | 必填 | 说明 | 117| ------ | --------------------------------------------------- | ---- | --------------------------------------------------------- | 118| value | [NavigationTitleMode](#navigationtitlemode枚举说明) | 是 | 页面标题栏显示模式。<br/>默认值:NavigationTitleMode.Free | 119 120### toolBar<sup>(deprecated)</sup> 121 122toolBar(value: object | CustomBuilder) 123 124设置工具栏内容。不设置时不显示工具栏。items均分底部工具栏,在每个均分内容区布局文本和图标,文本超长时,逐级缩小,缩小之后换行,最后...截断。 125 126从API version 10开始,该接口不再维护,推荐使用[toolbarConfiguration](#toolbarconfiguration10)代替。 127 128**系统能力:** SystemCapability.ArkUI.ArkUI.Full 129 130**参数:** 131 132| 参数名 | 类型 | 必填 | 说明 | 133| ------ | ------------------------------------------------------------ | ---- | ------------ | 134| value | object \| [CustomBuilder](ts-types.md#custombuilder8) | 是 | 工具栏内容。 | 135 136**object类型说明:** 137 138| 名称 | 类型 | 必填 | 说明 | 139| ------ | ------------- | ---- | --------------- | 140| value | string | 是 | 工具栏单个选项的显示文本。 | 141| icon | string | 否 | 工具栏单个选项的图标资源路径。 | 142| action | () => void | 否 | 当前选项被选中的事件回调。 | 143 144### toolbarConfiguration<sup>10+</sup> 145 146toolbarConfiguration(value: Array<ToolbarItem> | CustomBuilder, options?: NavigationToolbarOptions) 147 148> **说明:** 149> 150> 不支持通过SymbolGlyphModifier对象的fontSize属性修改图标大小、effectStrategy属性修改动效、symbolEffect属性修改动效类型。 151 152 153设置工具栏内容。不设置时不显示工具栏。 154 155**卡片能力:** 从API version 10开始,该接口支持在ArkTS卡片中使用。 156 157**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 158 159**系统能力:** SystemCapability.ArkUI.ArkUI.Full 160 161**参数:** 162 163| 参数名 | 类型 | 必填 | 说明 | 164| ------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | 165| value | Array<[ToolbarItem](#toolbaritem10)> \| [CustomBuilder](ts-types.md#custombuilder8) | 是 | 工具栏内容,使用Array<[ToolbarItem](#toolbaritem10)>写法设置的工具栏有如下特性:<br/>工具栏所有选项均分底部工具栏,在每个均分内容区布局文本和图标。<br/>文本超长时,若工具栏选项个数小于5个,优先拓展选项的宽度,最大宽度与屏幕等宽,其次逐级缩小,缩小之后换行,最后...截断。<br/>竖屏最多支持显示5个图标,多余的图标会被放入自动生成的更多图标。横屏时,如果为[Split](#navigationmode9枚举说明)模式,仍按照竖屏规则显示,如果为[Stack](#navigationmode9枚举说明)模式需配合menus属性的Array<[NavigationMenuItem](#navigationmenuitem)>使用,底部工具栏会自动隐藏,同时底部工具栏所有选项移动至页面右上角菜单。<br/>使用[CustomBuilder](ts-types.md#custombuilder8)写法为用户自定义工具栏选项,除均分底部工具栏外不具备以上功能。 | 166| options | [NavigationToolbarOptions](#navigationtoolbaroptions11)<sup>11+</sup> | 否 | 工具栏选项。 | 167 168### hideToolBar 169 170hideToolBar(value: boolean) 171 172设置是否隐藏工具栏。 173 174**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 175 176**系统能力:** SystemCapability.ArkUI.ArkUI.Full 177 178**参数:** 179 180| 参数名 | 类型 | 必填 | 说明 | 181| ------ | ------- | ---- | ------------------------------------------------------------ | 182| value | boolean | 是 | 是否隐藏工具栏。<br/>默认值:false<br/>true: 隐藏工具栏。<br/>false: 显示工具栏。 | 183 184### hideToolBar<sup>14+</sup> 185 186hideToolBar(hide: boolean, animated: boolean) 187 188设置是否隐藏工具栏,设置是否使用动画显隐工具栏。 189 190**原子化服务API:** 从API version 14开始,该接口支持在原子化服务中使用。 191 192**系统能力:** SystemCapability.ArkUI.ArkUI.Full 193 194**参数:** 195 196| 参数名 | 类型 | 必填 | 说明 | 197| ------ | ------- | ---- | ------------------------------------------------------------ | 198| hide | boolean | 是 | 是否隐藏工具栏。<br/>默认值:false<br/>true: 隐藏工具栏。<br/>false: 显示工具栏。 | 199| animated | boolean | 是 | 设置是否使用动画显隐工具栏。<br/>默认值:false<br/>true: 使用动画显示隐藏工具栏。<br/>false: 不使用动画显示隐藏工具栏。 | 200 201### hideTitleBar 202 203hideTitleBar(value: boolean) 204 205设置是否隐藏标题栏。 206 207**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 208 209**系统能力:** SystemCapability.ArkUI.ArkUI.Full 210 211**参数:** 212 213| 参数名 | 类型 | 必填 | 说明 | 214| ------ | ------- | ---- | ------------------------------------------------------------ | 215| value | boolean | 是 | 是否隐藏标题栏。<br/>默认值:false<br/>true: 隐藏标题栏。<br/>false: 显示标题栏。 | 216 217### hideTitleBar<sup>14+</sup> 218 219hideTitleBar(hide: boolean, animated: boolean) 220 221设置是否隐藏标题栏,设置是否使用动画显隐标题栏。 222 223**原子化服务API:** 从API version 14开始,该接口支持在原子化服务中使用。 224 225**系统能力:** SystemCapability.ArkUI.ArkUI.Full 226 227**参数:** 228 229| 参数名 | 类型 | 必填 | 说明 | 230| ------ | ------- | ---- | ------------------------------------------------------------ | 231| hide | boolean | 是 | 是否隐藏标题栏。<br/>默认值:false<br/>true: 隐藏标题栏。<br/>false: 显示标题栏。 | 232| animated | boolean | 是 | 设置是否使用动画显隐标题栏。<br/>默认值:false<br/>true: 使用动画显示隐藏标题栏。<br/>false: 不使用动画显示隐藏标题栏。 | 233 234### hideBackButton 235 236hideBackButton(value: boolean) 237 238设置是否隐藏标题栏中的返回键。返回键仅针对[titleMode](#titlemode)为NavigationTitleMode.Mini时才生效。 239 240**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 241 242**系统能力:** SystemCapability.ArkUI.ArkUI.Full 243 244**参数:** 245 246| 参数名 | 类型 | 必填 | 说明 | 247| ------ | ------- | ---- | ------------------------------------------------------------ | 248| value | boolean | 是 | 是否隐藏标题栏中的返回键。 <br/>默认值:false<br/>true: 隐藏返回键。<br/>false: 显示返回键。 | 249 250### navBarWidth<sup>9+</sup> 251 252navBarWidth(value: Length) 253 254设置导航栏宽度。仅在Navigation组件分栏时生效。 255 256**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 257 258**系统能力:** SystemCapability.ArkUI.ArkUI.Full 259 260**参数:** 261 262| 参数名 | 类型 | 必填 | 说明 | 263| ------ | ---------------------------- | ---- | ----------------------------------------- | 264| value | [Length](ts-types.md#length) | 是 | 导航栏宽度。<br/>默认值:240<br/>单位:vp<br/>undefined:行为不做处理,导航栏宽度与默认值保持一致。 | 265 266### navBarPosition<sup>9+</sup> 267 268navBarPosition(value: NavBarPosition) 269 270设置导航栏位置。仅在Navigation组件分栏时生效。 271 272**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 273 274**系统能力:** SystemCapability.ArkUI.ArkUI.Full 275 276**参数:** 277 278| 参数名 | 类型 | 必填 | 说明 | 279| ------ | ------------------------------------------ | ---- | --------------------------------------------- | 280| value | [NavBarPosition](#navbarposition9枚举说明) | 是 | 导航栏位置。<br/>默认值:NavBarPosition.Start | 281 282### mode<sup>9+</sup> 283 284mode(value: NavigationMode) 285 286设置导航栏的显示模式。支持Stack、Split与Auto模式。 287 288**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 289 290**系统能力:** SystemCapability.ArkUI.ArkUI.Full 291 292**参数:** 293 294| 参数名 | 类型 | 必填 | 说明 | 295| ------ | ------------------------------------------ | ---- | ------------------------------------------------------------ | 296| value | [NavigationMode](#navigationmode9枚举说明) | 是 | 导航栏的显示模式。<br/>默认值:NavigationMode.Auto<br/>自适应:基于组件宽度自适应单栏和双栏。 | 297 298### backButtonIcon<sup>9+</sup> 299 300backButtonIcon(value: string | PixelMap | Resource | SymbolGlyphModifier) 301 302> **说明:** 303> 304> 不支持通过SymbolGlyphModifier对象的fontSize属性修改图标大小、effectStrategy属性修改动效、symbolEffect属性修改动效类型。 305 306 307设置标题栏中返回键图标。 308 309**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 310 311**系统能力:** SystemCapability.ArkUI.ArkUI.Full 312 313**参数:** 314 315| 参数名 | 类型 | 必填 | 说明 | 316| ------ | ------------------------------------------------------------ | ---- | -------------------- | 317| 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) | 是 | 标题栏中返回键图标。 | 318 319### hideNavBar<sup>9+</sup> 320 321hideNavBar(value: boolean) 322 323设置是否隐藏导航栏。设置为true时,隐藏Navigation的导航栏,包括标题栏、内容区和工具栏。如果此时路由栈中存在NavDestination页面,则直接显示栈顶NavDestination页面,反之显示空白。 324 325从API Version 9开始到API Version 10仅在双栏模式下生效。从API Version 11开始在单栏、双栏与自适应模式均生效。 326 327**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 328 329**系统能力:** SystemCapability.ArkUI.ArkUI.Full 330 331**参数:** 332 333| 参数名 | 类型 | 必填 | 说明 | 334| ------ | ------- | ---- | ---------------------------------- | 335| value | boolean | 是 | 是否隐藏导航栏。<br/>默认值:false | 336 337### navDestination<sup>10+</sup> 338 339navDestination(builder: (name: string, param: unknown) => void) 340 341创建NavDestination组件。使用builder函数,基于name和param构造NavDestination组件。builder下只能有一个根节点。builder中允许在NavDestination组件外包含一层自定义组件, 但自定义组件不允许设置属性和事件,否则仅显示空白。 342 343**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 344 345**系统能力:** SystemCapability.ArkUI.ArkUI.Full 346 347**参数:** 348 349| 参数名 | 类型 | 必填 | 说明 | 350| ------- | -------------------------------------- | ---- | ------------------------ | 351| builder | (name: string, param: unknown) => void | 是 | 创建NavDestination组件。name:NavDestination页面名称。param:Navdestination页面详细参数。 | 352 353### navBarWidthRange<sup>10+</sup> 354 355navBarWidthRange(value: [Dimension, Dimension]) 356 357设置导航栏最小和最大宽度(双栏模式下生效)。 358 359**规则:** 优先级规则详见说明。 360 361**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 362 363**系统能力:** SystemCapability.ArkUI.ArkUI.Full 364 365**参数:** 366 367| 参数名 | 类型 | 必填 | 说明 | 368| ------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | 369| value | [[Dimension](ts-types.md#dimension10), [Dimension](ts-types.md#dimension10)] | 是 | 导航栏最小和最大宽度。<br/>默认值:最小默认值 240,最大默认值为组件宽度的40% ,且不大于 432,如果只设置一个值,则未设置的值按照默认值计算。<br/>单位:vp | 370 371### minContentWidth<sup>10+</sup> 372 373minContentWidth(value: Dimension) 374 375设置导航栏内容区最小宽度(双栏模式下生效)。 376 377**规则:** 优先级规则详见说明。 378 379**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 380 381**系统能力:** SystemCapability.ArkUI.ArkUI.Full 382 383**参数:** 384 385| 参数名 | 类型 | 必填 | 说明 | 386| ------- | ------------------------------------ | ---- | ------------------------------------------------------------ | 387| value | [Dimension](ts-types.md#dimension10) | 是 | 导航栏内容区最小宽度。<br/>默认值:360<br/>单位:vp<br/>undefined:行为不做处理,导航栏内容区最小宽度与默认值保持一致。<br/>Auto模式断点计算:默认600vp,minNavBarWidth(240vp) + minContentWidth (360vp) | 388 389> **说明:** 390> 391> 1. 仅设置navBarWidth,不支持Navigation分割线拖拽。 392> 393> 2. navBarWidthRange指定分割线可以拖拽范围。如果不设置值,则按照默认值处理。拖拽范围需要满足navBarWidthRange设置的范围和minContentWidth限制。 394> 395> 3. Navigation显示范围缩小:a. 缩小内容区大小。如果不设置minContentWidth属性,则可以缩小内容区至0, 否则最小缩小至minContentWidth。b. 缩小导航栏大小,缩小时需要满足导航栏宽度大于navBarRange的下限。c. 对显示内容进行裁切。 396 397### ignoreLayoutSafeArea<sup>12+</sup> 398 399ignoreLayoutSafeArea(types?: Array<LayoutSafeAreaType>, edges?: Array<LayoutSafeAreaEdge>) 400 401控制组件的布局,使其扩展到非安全区域 402 403**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 404 405**系统能力:** SystemCapability.ArkUI.ArkUI.Full 406 407**参数:** 408 409| 参数名 | 类型 | 必填 | 说明 | 410| ------ | -------------------------------------------------- | ---- | ------------------------------------------------------------ | 411| types | Array <[LayoutSafeAreaType](ts-types.md#layoutsafeareatype12)> | 否 | 配置扩展安全区域的类型。<br />默认值: <br />[LayoutSafeAreaType.SYSTEM] | 412| edges | Array <[LayoutSafeAreaEdge](ts-types.md#layoutsafeareaedge12)> | 否 | 配置扩展安全区域的方向。<br /> 默认值: <br />[LayoutSafeAreaEdge.TOP, LayoutSafeAreaEdge.BOTTOM]。| 413 414> **说明:** 415> 416> 组件设置LayoutSafeArea之后生效的条件为: 417> 设置LayoutSafeAreaType.SYSTEM时,组件的边界与非安全区域重合时组件能够延伸到非安全区域下。例如:设备顶部状态栏高度100,组件在屏幕中纵向方位的绝对偏移需要在0到100之间。 418> 419> 若组件延伸到非安全区域内,此时在非安全区域里触发的事件(例如:点击事件)等可能会被系统拦截,优先响应状态栏等系统组件。 420 421### systemBarStyle<sup>12+</sup> 422 423systemBarStyle(style: Optional<SystemBarStyle>) 424 425当Navigation中显示Navigation首页时,设置对应系统状态栏的样式。 426 427**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 428 429**系统能力:** SystemCapability.ArkUI.ArkUI.Full 430 431**参数:** 432 433| 参数名 | 类型 | 必填 | 说明 | 434| ------ | -------------- | ---- | ------------------ | 435| style | Optional<[SystemBarStyle](../js-apis-window.md#systembarstyle12)> | 是 | 系统状态栏样式。 | 436 437> **使用说明:** 438> 439> 1. 不建议混合使用systemBarStyle属性和window设置状态栏样式的相关接口,例如:[setWindowSystemBarProperties](../js-apis-window.md#setwindowsystembarproperties9)。 440> 2. 初次设置Navigation/NavDestination的systemBarStyle属性时,会备份当前状态栏样式用于后续的恢复场景。 441> 3. Navigation总是以首页(页面栈内没有NavDestination时)或者栈顶NavDestination设置的状态栏样式为准。 442> 4. Navigation首页或者任何栈顶NavDestination页面,如果设置了有效的systemBarStyle,则会使用设置的样式,反之如果之前已经备份了样式,则使用备份的样式,否则不做任何处理。 443> 5. [Split](#navigationmode9枚举说明)模式下的Navigation,如果内容区没有NavDestination,则遵从Navigation首页的设置,反之则遵从栈顶NavDestination的设置。 444> 6. 仅支持在主窗口的主页面中使用systemBarStyle设置状态栏样式。 445> 7. 仅当Navigation占满整个页面时,设置的样式才会生效,当Navigation没有占满整个页面时,如果有备份的样式,则恢复备份的样式。 446> 8. 当页面设置不同样式时,在页面转场开始时生效。 447> 9. 非全屏窗口下,Navigation/NavDestination设置的状态栏不生效。 448 449## 事件 450 451### onTitleModeChange 452 453onTitleModeChange(callback: (titleMode: NavigationTitleMode) => void) 454 455当[titleMode](#titlemode)为NavigationTitleMode.Free时,随着可滚动组件的滑动标题栏模式发生变化时触发此回调。 456 457**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 458 459**系统能力:** SystemCapability.ArkUI.ArkUI.Full 460 461**参数:** 462 463| 参数名 | 类型 | 必填 | 说明 | 464| --------- | --------------------------------------------------- | ---- | ---------- | 465| titleMode | [NavigationTitleMode](#navigationtitlemode枚举说明) | 是 | 标题模式。 | 466 467### onNavBarStateChange<sup>9+</sup> 468 469onNavBarStateChange(callback: (isVisible: boolean) => void) 470 471导航栏显示状态切换时触发该回调。 472 473**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 474 475**系统能力:** SystemCapability.ArkUI.ArkUI.Full 476 477**参数:** 478 479| 参数名 | 类型 | 必填 | 说明 | 480| --------- | ------- | ---- | ---------------------------------------------- | 481| isVisible | boolean | 是 | isVisible为true时表示显示,为false时表示隐藏。 | 482 483### onNavigationModeChange<sup>11+</sup> 484 485onNavigationModeChange(callback: (mode: NavigationMode) => void) 486 487当Navigation首次显示或者单双栏状态发生变化时触发该回调。 488 489**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 490 491**系统能力:** SystemCapability.ArkUI.ArkUI.Full 492 493**参数:** 494 495| 参数名 | 类型 | 必填 | 说明 | 496| --------- | ------- | ---- | ---------------------------------------------- | 497| mode | [NavigationMode](#navigationmode9枚举说明) | 是 | NavigationMode.Split: 当前Navigation显示为双栏;<br/>NavigationMode.Stack: 当前Navigation显示为单栏。| 498 499### customNavContentTransition<sup>11+</sup> 500 501customNavContentTransition(delegate:(from: NavContentInfo, to: NavContentInfo, operation: NavigationOperation) => NavigationAnimatedTransition | undefined) 502 503自定义转场动画回调。 504 505**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 506 507**系统能力:** SystemCapability.ArkUI.ArkUI.Full 508 509**参数:** 510 511| 参数名 | 类型 | 必填 | 说明 | 512| --------- | ----------------------------------------------------- | ---- | ----------------------- | 513| from | [NavContentInfo](#navcontentinfo11) | 是 | 退场Destination的页面。 | 514| to | [NavContentInfo](#navcontentinfo11) | 是 | 进场Destination的页面。 | 515| operation | [NavigationOperation](#navigationoperation11枚举说明) | 是 | 转场类型。 | 516 517**返回值:** 518 519| 类型 | 说明 | 520| ------------------------------------------------------------ | ------------------------------------------------------------ | 521| [NavigationAnimatedTransition](#navigationanimatedtransition11) \| undefined | 自定义转场动画协议。<br/>undefined: 返回未定义,执行默认转场动效。 | 522 523## NavPathStack<sup>10+</sup> 524 525Navigation路由栈,允许被继承<sup>12+</sup>。开发者可以在派生类中新增属性方法,也可以重写基类NavPathStack的方法。派生类对象可以替代基类NavPathStack对象使用。使用示例参见[示例10](#示例10)。 526 527### pushPath<sup>10+</sup> 528 529pushPath(info: NavPathInfo, animated?: boolean): void 530 531将info指定的NavDestination页面信息入栈。 532 533**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 534 535**系统能力:** SystemCapability.ArkUI.ArkUI.Full 536 537**参数:** 538 539| 参数名 | 类型 | 必填 | 说明 | 540| ---- | ----------------------------- | ---- | -------------------- | 541| info | [NavPathInfo](#navpathinfo10) | 是 | NavDestination页面的信息。 | 542| animated<sup>11+</sup> | boolean | 否 | 是否支持转场动画,默认值:true。 | 543 544### pushPath<sup>12+</sup> 545 546pushPath(info: NavPathInfo, options?: NavigationOptions): void 547 548将info指定的NavDestination页面信息入栈,具体根据options中指定不同的[LaunchMode](#launchmode12枚举说明),有不同的行为。 549 550**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 551 552**系统能力:** SystemCapability.ArkUI.ArkUI.Full 553 554**参数:** 555 556| 参数名 | 类型 | 必填 | 说明 | 557| ---- | ----------------------------- | ---- | -------------------- | 558| info | [NavPathInfo](#navpathinfo10) | 是 | NavDestination页面的信息。 | 559| options | [NavigationOptions](#navigationoptions12) | 否 | 页面栈操作选项。 | 560 561### pushPathByName<sup>10+</sup> 562 563pushPathByName(name: string, param: unknown, animated?: boolean): void 564 565将name指定的NavDestination页面信息入栈,传递的数据为param。 566 567**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 568 569**系统能力:** SystemCapability.ArkUI.ArkUI.Full 570 571**参数:** 572 573| 参数名 | 类型 | 必填 | 说明 | 574| ----- | ------- | ---- | --------------------- | 575| name | string | 是 | NavDestination页面名称。 | 576| param | unknown | 是 | NavDestination页面详细参数。 | 577| animated<sup>11+</sup> | boolean | 否 | 是否支持转场动画,默认值:true。 | 578 579### pushPathByName<sup>11+</sup> 580 581pushPathByName(name: string, param: Object, onPop: Callback\<PopInfo>, animated?: boolean): void 582 583将name指定的NavDestination页面信息入栈,传递的数据为param,添加onPop回调接收入栈页面出栈时的返回结果,并进行处理。 584 585**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 586 587**系统能力:** SystemCapability.ArkUI.ArkUI.Full 588 589**参数:** 590 591| 参数名 | 类型 | 必填 | 说明 | 592|------|------|------|------| 593| name | string | 是 | NavDestination页面名称。 | 594| param | Object | 是 | NavDestination页面详细参数。 | 595| onPop | Callback\<[PopInfo](#popinfo11)> | 是 | Callback回调,用于页面出栈时触发该回调处理返回结果。仅pop中设置result参数后触发。 | 596| animated | boolean | 否 | 是否支持转场动画,默认值:true。 | 597 598### pushDestination<sup>11+</sup> 599 600pushDestination(info: NavPathInfo, animated?: boolean): Promise<void> 601 602将info指定的NavDestination页面信息入栈,使用Promise异步回调返回接口调用结果。 603 604**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 605 606**系统能力:** SystemCapability.ArkUI.ArkUI.Full 607 608**参数:** 609 610| 参数名 | 类型 | 必填 | 说明 | 611| ---- | ----------------------------- | ---- | -------------------- | 612| info | [NavPathInfo](#navpathinfo10) | 是 | NavDestination页面的信息。 | 613| animated | boolean | 否 | 是否支持转场动画,默认值:true。 | 614 615**返回值:** 616 617| 类型 | 说明 | 618| ------------------- | --------- | 619| Promise<void> | 异常返回结果。 | 620 621**错误码:** 622 623以下错误码的详细介绍请参见[通用错误码](../../errorcode-universal.md)和[ohos.router(页面路由)](../errorcode-router.md)错误码。 624 625| 错误码ID | 错误信息 | 626| --------- | ------- | 627| 401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed. | 628| 100001 | Internal error.| 629| 100005 | Builder function not registered. | 630| 100006 | NavDestination not found.| 631 632### pushDestination<sup>12+</sup> 633 634pushDestination(info: NavPathInfo, options?: NavigationOptions): Promise<void> 635 636将info指定的NavDestination页面信息入栈,使用Promise异步回调返回接口调用结果,具体根据options中指定不同的[LaunchMode](#launchmode12枚举说明),有不同的行为。 637 638**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 639 640**系统能力:** SystemCapability.ArkUI.ArkUI.Full 641 642**参数:** 643 644| 参数名 | 类型 | 必填 | 说明 | 645| ---- | ----------------------------- | ---- | -------------------- | 646| info | [NavPathInfo](#navpathinfo10) | 是 | NavDestination页面的信息。 | 647| options | [NavigationOptions](#navigationoptions12) | 否 | 页面栈操作选项。 | 648 649**返回值:** 650 651| 类型 | 说明 | 652| ------------------- | --------- | 653| Promise<void> | 异常返回结果。 | 654 655**错误码:** 656 657以下错误码的详细介绍请参见[通用错误码](../../errorcode-universal.md)和[ohos.router(页面路由)](../errorcode-router.md)错误码。 658 659| 错误码ID | 错误信息 | 660| --------- | ------- | 661| 401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed. | 662| 100001 | Internal error.| 663| 100005 | Builder function not registered. | 664| 100006 | NavDestination not found.| 665 666### pushDestinationByName<sup>11+</sup> 667 668pushDestinationByName(name: string, param: Object, animated?: boolean): Promise<void> 669 670将name指定的NavDestination页面信息入栈,传递的数据为param,使用Promise异步回调返回接口调用结果。 671 672**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 673 674**系统能力:** SystemCapability.ArkUI.ArkUI.Full 675 676**参数:** 677 678| 参数名 | 类型 | 必填 | 说明 | 679| ----- | ------- | ---- | --------------------- | 680| name | string | 是 | NavDestination页面名称。 | 681| param | Object | 是 | NavDestination页面详细参数。 | 682| animated | boolean | 否 | 是否支持转场动画,默认值:true。 | 683 684**返回值:** 685 686| 类型 | 说明 | 687| ------------------- | --------- | 688| Promise<void> | 异常返回结果。 | 689 690**错误码:** 691 692以下错误码的详细介绍请参见[通用错误码](../../errorcode-universal.md)和[ohos.router(页面路由)](../errorcode-router.md)错误码。 693 694| 错误码ID | 错误信息 | 695| --------- | ------- | 696| 401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed. | 697| 100001 | Internal error.| 698| 100005 | Builder function not registered. | 699| 100006 | NavDestination not found.| 700 701### pushDestinationByName<sup>11+</sup> 702 703pushDestinationByName(name: string, param: Object, onPop: Callback\<PopInfo>, animated?: boolean): Promise<void> 704 705将name指定的NavDestination页面信息入栈,传递的数据为param,并且添加用于页面出栈时处理返回结果的OnPop回调,使用Promise异步回调返回接口调用结果。 706 707**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 708 709**系统能力:** SystemCapability.ArkUI.ArkUI.Full 710 711**参数:** 712 713| 参数名 | 类型 | 必填 | 说明 | 714| ----- | ------- | ---- | --------------------- | 715| name | string | 是 | NavDestination页面名称。 | 716| param | Object | 是 | NavDestination页面详细参数。 | 717| onPop | Callback\<[PopInfo](#popinfo11)> | 是 | Callback回调,用于页面出栈时处理返回结果。仅pop中设置result参数后触发。 | 718| animated | boolean | 否 | 是否支持转场动画,默认值:true。 | 719 720**返回值:** 721 722| 类型 | 说明 | 723| ------------------- | --------- | 724| Promise<void> | 异常返回结果。 | 725 726**错误码:** 727 728以下错误码的详细介绍请参见[通用错误码](../../errorcode-universal.md)和[ohos.router(页面路由)](../errorcode-router.md)错误码。 729 730| 错误码ID | 错误信息 | 731| --------- | ------- | 732| 401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed. | 733| 100001 | Internal error.| 734| 100005 | Builder function not registered. | 735| 100006 | NavDestination not found.| 736 737### replacePath<sup>11+</sup> 738 739replacePath(info: NavPathInfo, animated?: boolean): void 740 741将当前页面栈栈顶退出,将info指定的NavDestination页面信息入栈。 742 743**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 744 745**系统能力:** SystemCapability.ArkUI.ArkUI.Full 746 747**参数:** 748 749| 参数名 | 类型 | 必填 | 说明 | 750| ---- | ----------------------------- | ---- | -------------------- | 751| info | [NavPathInfo](#navpathinfo10) | 是 | 新栈顶页面参数信息 | 752| animated<sup>11+</sup> | boolean | 否 | 是否支持转场动画,默认值:true。 | 753 754### replacePath<sup>12+</sup> 755 756replacePath(info: NavPathInfo, options?: NavigationOptions): void 757 758替换页面栈操作,具体根据options中指定不同的[LaunchMode](#launchmode12枚举说明),有不同的行为。 759 760**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 761 762**系统能力:** SystemCapability.ArkUI.ArkUI.Full 763 764**参数:** 765 766| 参数名 | 类型 | 必填 | 说明 | 767| ---- | ----------------------------- | ---- | -------------------- | 768| info | [NavPathInfo](#navpathinfo10) | 是 | 新栈顶页面参数信息。 | 769| options | [NavigationOptions](#navigationoptions12) | 否 | 页面栈操作选项。 | 770 771### replacePathByName<sup>11+</sup> 772 773replacePathByName(name: string, param: Object, animated?: boolean): void 774 775将当前页面栈栈顶退出,将name指定的页面入栈。 776 777**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 778 779**系统能力:** SystemCapability.ArkUI.ArkUI.Full 780 781**参数:** 782 783| 参数名 | 类型 | 必填 | 说明 | 784| ----- | ------- | ---- | --------------------- | 785| name | string | 是 | NavDestination页面名称。 | 786| param | Object | 是 | NavDestination页面详细参数。 | 787| animated<sup>11+</sup> | boolean | 否 | 是否支持转场动画,默认值:true。 | 788 789### removeByIndexes<sup>11+</sup> 790 791removeByIndexes(indexes: Array<number\>): number 792 793将页面栈内索引值在indexes中的NavDestination页面删除。 794 795**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 796 797**系统能力:** SystemCapability.ArkUI.ArkUI.Full 798 799**参数:** 800 801| 参数名 | 类型 | 必填 | 说明 | 802| ----- | ------- | ---- | --------------------- | 803| indexes | Array<number\> | 是 | 待删除NavDestination页面的索引值数组。 | 804 805**返回值:** 806 807| 类型 | 说明 | 808| ----------- | ------------------------ | 809| number | 返回删除的NavDestination页面数量。 | 810 811### removeByName<sup>11+</sup> 812 813removeByName(name: string): number 814 815将页面栈内指定name的NavDestination页面删除。 816 817**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 818 819**系统能力:** SystemCapability.ArkUI.ArkUI.Full 820 821**参数:** 822 823| 参数名 | 类型 | 必填 | 说明 | 824| ----- | ------- | ---- | --------------------- | 825| name | string | 是 | 删除的NavDestination页面的名字。 | 826 827**返回值:** 828 829| 类型 | 说明 | 830| ----------- | ------------------------ | 831| number | 返回删除的NavDestination页面数量。 | 832 833### removeByNavDestinationId<sup>12+</sup> 834 835removeByNavDestinationId(navDestinationId: string): boolean 836 837将页面栈内指定navDestinationId的NavDestination页面删除。navDestinationId可以在NavDestination的[onReady](ts-basic-components-navdestination.md#onready11)回调中获取,也可以在[NavDestinationInfo](../js-apis-arkui-observer.md#navdestinationinfo)中获取。 838 839**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 840 841**系统能力:** SystemCapability.ArkUI.ArkUI.Full 842 843**参数:** 844 845| 参数名 | 类型 | 必填 | 说明 | 846| ----- | ------- | ---- | --------------------- | 847| navDestinationId | string | 是 | 删除的NavDestination页面的唯一标识符navDestinationId。 | 848 849**返回值:** 850 851| 类型 | 说明 | 852| ----------- | ------------------------ | 853| boolean | 返回是否成功删除该页面,true为删除成功。 | 854 855### pop<sup>10+</sup> 856 857pop(animated?: boolean): NavPathInfo | undefined 858 859弹出路由栈栈顶元素。 860 861**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 862 863**系统能力:** SystemCapability.ArkUI.ArkUI.Full 864 865**参数:** 866 867| 参数名 | 类型 | 必填 | 说明 | 868| ---- | ----------------------------- | ---- | -------------------- | 869| animated<sup>11+</sup> | boolean | 否 | 是否支持转场动画,默认值:true。 | 870 871**返回值:** 872 873| 类型 | 说明 | 874| ----------- | ------------------------ | 875| [NavPathInfo](#navpathinfo10) | 返回栈顶NavDestination页面的信息。 | 876| undefined | 当路由栈为空时返回undefined。 | 877 878### pop<sup>11+</sup> 879 880pop(result: Object, animated?: boolean): NavPathInfo | undefined 881 882弹出路由栈栈顶元素,并触发onPop回调传入页面处理结果。 883 884**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 885 886**系统能力:** SystemCapability.ArkUI.ArkUI.Full 887 888**参数:** 889 890| 参数名 | 类型 | 必填 | 说明 | 891| ---- | ----------------------------- | ---- | -------------------- | 892| result | Object | 是 | 页面自定义处理结果。不支持boolean类型。 | 893| animated | boolean | 否 | 是否支持转场动画,默认值:true。 | 894 895**返回值:** 896 897| 类型 | 说明 | 898| ----------- | ------------------------ | 899| [NavPathInfo](#navpathinfo10) | 返回栈顶NavDestination页面的信息。 | 900| undefined | 当路由栈为空时返回undefined。 | 901 902### popToName<sup>10+</sup> 903 904popToName(name: string, animated?: boolean): number 905 906回退路由栈到由栈底开始第一个名为name的NavDestination页面。 907 908**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 909 910**系统能力:** SystemCapability.ArkUI.ArkUI.Full 911 912**参数:** 913 914| 参数名 | 类型 | 必填 | 说明 | 915| ---- | ------ | ---- | ------------------- | 916| name | string | 是 | NavDestination页面名称。 | 917| animated<sup>11+</sup> | boolean | 否 | 是否支持转场动画,默认值:true。 | 918 919**返回值:** 920 921| 类型 | 说明 | 922| ------ | ---------------------------------------- | 923| number | 如果栈中存在名为name的NavDestination页面,则返回由栈底开始第一个名为name的NavDestination页面的索引,否则返回-1。 | 924 925### popToName<sup>11+</sup> 926 927popToName(name: string, result: Object, animated?: boolean): number 928 929回退路由栈到由栈底开始第一个名为name的NavDestination页面,并触发onPop回调传入页面处理结果。 930 931**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 932 933**系统能力:** SystemCapability.ArkUI.ArkUI.Full 934 935**参数:** 936 937| 参数名 | 类型 | 必填 | 说明 | 938| ---- | ------ | ---- | ------------------- | 939| name | string | 是 | NavDestination页面名称。 | 940| result | Object | 是 | 页面自定义处理结果。不支持boolean类型。 | 941| animated | boolean | 否 | 是否支持转场动画,默认值:true。 | 942 943**返回值:** 944 945| 类型 | 说明 | 946| ------ | ---------------------------------------- | 947| number | 如果栈中存在名为name的NavDestination页面,则返回由栈底开始第一个名为name的NavDestination页面的索引,否则返回-1。 | 948 949### popToIndex<sup>10+</sup> 950 951popToIndex(index: number, animated?: boolean): void 952 953回退路由栈到index指定的NavDestination页面。 954 955**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 956 957**系统能力:** SystemCapability.ArkUI.ArkUI.Full 958 959**参数:** 960 961| 参数名 | 类型 | 必填 | 说明 | 962| ----- | ------ | ---- | ---------------------- | 963| index | number | 是 | NavDestination页面的位置索引。 | 964| animated<sup>11+</sup> | boolean | 否 | 是否支持转场动画,默认值:true。 | 965 966### popToIndex<sup>11+</sup> 967 968popToIndex(index: number, result: Object, animated?: boolean): void 969 970回退路由栈到index指定的NavDestination页面,并触发onPop回调传入页面处理结果。 971 972**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 973 974**系统能力:** SystemCapability.ArkUI.ArkUI.Full 975 976**参数:** 977 978| 参数名 | 类型 | 必填 | 说明 | 979| ----- | ------ | ---- | ---------------------- | 980| index | number | 是 | NavDestination页面的位置索引。 | 981| result | Object | 是 | 页面自定义处理结果。不支持boolean类型。 | 982| animated | boolean | 否 | 是否支持转场动画,默认值:true。 | 983 984### moveToTop<sup>10+</sup> 985 986moveToTop(name: string, animated?: boolean): number 987 988将由栈底开始第一个名为name的NavDestination页面移到栈顶。 989 990**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 991 992**系统能力:** SystemCapability.ArkUI.ArkUI.Full 993 994**参数:** 995 996| 参数名 | 类型 | 必填 | 说明 | 997| ---- | ------ | ---- | ------------------- | 998| name | string | 是 | NavDestination页面名称。 | 999| animated<sup>11+</sup> | boolean | 否 | 是否支持转场动画,默认值:true。 | 1000 1001**返回值:** 1002 1003| 类型 | 说明 | 1004| ------ | ---------------------------------------- | 1005| number | 如果栈中存在名为name的NavDestination页面,则返回由栈底开始第一个名为name的NavDestination页面的当前索引,否则返回-1。 | 1006 1007### moveIndexToTop<sup>10+</sup> 1008 1009moveIndexToTop(index: number, animated?: boolean): void 1010 1011将index指定的NavDestination页面移到栈顶。 1012 1013**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1014 1015**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1016 1017**参数:** 1018 1019| 参数名 | 类型 | 必填 | 说明 | 1020| ----- | ------ | ---- | ---------------------- | 1021| index | number | 是 | NavDestination页面的位置索引。 | 1022| animated<sup>11+</sup> | boolean | 否 | 是否支持转场动画,默认值:true。 | 1023 1024### clear<sup>10+</sup> 1025 1026clear(animated?: boolean): void 1027 1028清除栈中所有页面。 1029 1030**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1031 1032**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1033 1034**参数:** 1035 1036| 参数名 | 类型 | 必填 | 说明 | 1037| ----- | ------ | ---- | ---------------------- | 1038| animated<sup>11+</sup> | boolean | 否 | 是否支持转场动画,默认值:true。 | 1039 1040### getAllPathName<sup>10+</sup> 1041 1042getAllPathName(): Array<string\> 1043 1044获取栈中所有NavDestination页面的名称。 1045 1046**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1047 1048**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1049 1050**返回值:** 1051 1052| 类型 | 说明 | 1053| -------------- | -------------------------- | 1054| Array<string\> | 返回栈中所有NavDestination页面的名称。 | 1055 1056### getParamByIndex<sup>10+</sup> 1057 1058getParamByIndex(index: number): unknown | undefined 1059 1060获取index指定的NavDestination页面的参数信息。 1061 1062**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1063 1064**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1065 1066**参数:** 1067 1068| 参数名 | 类型 | 必填 | 说明 | 1069| ----- | ------ | ---- | ---------------------- | 1070| index | number | 是 | NavDestination页面的位置索引。 | 1071 1072**返回值:** 1073 1074| 类型 | 说明 | 1075| --------- | -------------------------- | 1076| unknown | 返回对应NavDestination页面的参数信息。 | 1077| undefined | 传入index无效时返回undefined。 | 1078 1079### getParamByName<sup>10+</sup> 1080 1081getParamByName(name: string): Array<unknown\> 1082 1083获取全部名为name的NavDestination页面的参数信息。 1084 1085**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1086 1087**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1088 1089**参数:** 1090 1091| 参数名 | 类型 | 必填 | 说明 | 1092| ---- | ------ | ---- | ------------------- | 1093| name | string | 是 | NavDestination页面名称。 | 1094 1095**返回值:** 1096 1097| 类型 | 说明 | 1098| --------------- | --------------------------------- | 1099| Array<unknown\> | 返回全部名为name的NavDestination页面的参数信息。 | 1100 1101### getIndexByName<sup>10+</sup> 1102 1103getIndexByName(name: string): Array<number\> 1104 1105获取全部名为name的NavDestination页面的位置索引。 1106 1107**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1108 1109**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1110 1111**参数:** 1112 1113| 参数名 | 类型 | 必填 | 说明 | 1114| ---- | ------ | ---- | ------------------- | 1115| name | string | 是 | NavDestination页面名称。 | 1116 1117**返回值:** 1118 1119| 类型 | 说明 | 1120| -------------- | --------------------------------- | 1121| Array<number\> | 返回全部名为name的NavDestination页面的位置索引。 | 1122 1123### size<sup>10+</sup> 1124 1125size(): number 1126 1127获取栈大小。 1128 1129**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1130 1131**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1132 1133**返回值:** 1134 1135| 类型 | 说明 | 1136| ------ | ------ | 1137| number | 返回栈大小。 | 1138 1139### disableAnimation<sup>11+</sup> 1140 1141disableAnimation(value: boolean): void 1142 1143关闭(true)或打开(false)当前Navigation中所有转场动画。 1144 1145**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1146 1147**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1148 1149**参数:** 1150 1151| 参数名 | 类型 | 必填 | 说明 | 1152| ----- | ------ | ---- | ---------------------- | 1153| value | boolean | 是 | 是否关闭转场动画,默认值:false。 | 1154 1155### getParent<sup>11+</sup> 1156 1157getParent(): NavPathStack | null 1158 1159获取父NavPathStack。<br/>当出现Navigation嵌套Navigation的情况时(可以是直接嵌套,也可以是间接嵌套),内部Navigation的NavPathStack能够获取到外层Navigation的NavPathStack。 1160 1161**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1162 1163**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1164 1165**返回值:** 1166 1167| 类型 | 说明 | 1168| ------ | ------ | 1169| [NavPathStack](#navpathstack10) \| null | 如果当前NavPathStack所属Navigation的外层有另外的一层Navigation,则能够获取到外层Navigation的NavPathStack。否则获取不到NavPathStack,返回null。 | 1170 1171### setInterception<sup>12+</sup> 1172 1173setInterception(interception: NavigationInterception): void 1174 1175设置Navigation页面跳转拦截回调。 1176 1177**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1178 1179**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1180 1181**参数:** 1182 1183| 参数名 | 类型 | 必填 | 说明 | 1184| ---- | ---- | --- | ---| 1185|interception| [NavigationInterception](#navigationinterception12)| 是 | 设置Navigation跳转拦截对象。| 1186 1187## NavPathInfo<sup>10+</sup> 1188 1189路由页面信息。 1190 1191### constructor 1192 1193constructor(name: string, param: unknown, onPop?: Callback\<PopInfo>, isEntry?: boolean) 1194 1195**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1196 1197**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1198 1199| 参数名 | 类型 | 必填 | 说明 | 1200| ----- | ------- | ---- | --------------------- | 1201| name | string | 是 | NavDestination页面名称。 | 1202| param | unknown | 否 | NavDestination页面详细参数。 | 1203| onPop<sup>11+</sup> | Callback\<[PopInfo](#popinfo11)> | 否 | NavDestination页面触发pop时返回的回调。 | 1204| isEntry<sup>12+</sup> | boolean | 否 | 标记NavDestination是否为入口页面。<br/>默认值:false <br/>标记清理时机:1、在当前navDestination页面触发一次全局back事件。2、应用退至后台。<br/>**说明**:<br/>入口NavDestination不响应应用内的全局back事件,直接触发应用间的全局back事件。 | 1205 1206## PopInfo<sup>11+</sup> 1207 1208下一个页面返回的回调信息载体。 1209 1210**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1211 1212**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1213 1214| 名称 | 类型 | 必填 | 说明 | 1215|------|-----|-----|-----| 1216| info | [NavPathInfo](#navpathinfo10) | 是 | 页面触发返回时的当前页面信息,系统自动获取填入,无需开发者传入。 | 1217| result | Object | 是 | 页面触发返回时的结果,开发者自定义对象。 | 1218 1219## NavContentInfo<sup>11+</sup> 1220 1221跳转Destination信息。 1222 1223**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1224 1225**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1226 1227| 名称 | 类型 | 必填 | 说明 | 1228|-------|-------|------|-------| 1229| name | string | 否 | NavDestination名称,如果为根视图(NavBar),则返回值为undefined。| 1230| index | number | 是 | NavDestination在NavPathStack中的序号, 如果为根视图(NavBar),则返回值为 -1。| 1231| mode | [NavDestinationMode](ts-basic-components-navdestination.md#navdestinationmode枚举说明) | 否 | NavDestination的模式,如果是根视图(NavBar),则返回值为undefined。| 1232| param<sup>12+</sup> | Object | 否 | NavDestination页面加载的参数。| 1233| navDestinationId<sup>12+</sup> | string | 否 | NavDestination的唯一标识符。| 1234 1235## NavigationAnimatedTransition<sup>11+</sup> 1236 1237自定义转场动画协议,开发者需实现该协议来定义Navigation路由跳转的跳转动画。 1238 1239**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1240 1241**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1242 1243| 名称 | 类型 | 必填 | 说明 | 1244|------|-----|-----|------| 1245| timeout | number | 否 | 动画超时结束时间。<br> 单位:ms。<br> 默认值:可交互动画无默认值,不可交互动画默认超时时间为1000ms。| 1246| transition | (transitionProxy : [NavigationTransitionProxy](#navigationtransitionproxy-11)) => void | 是 | 自定义转场动画执行回调。<br> transitionProxy: 自定义转场动画代理对象。| 1247| onTransitionEnd | (success: boolean) => void | 否 | 转场完成回调。<br> success: 转场是否成功。 | 1248| isInteractive<sup>12+</sup> | boolean | 否 | 本次转场动画是否为可交互转场。<br> 默认值:false。| 1249 1250## NavigationTransitionProxy <sup>11+</sup> 1251 1252自定义转场动画代理对象。 1253 1254**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1255 1256### 属性 1257 1258**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1259 1260**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1261 1262| 名称 | 类型 | 必填 | 说明 | 1263|------|-------|-----|-------| 1264| from | [NavContentInfo](#navcontentinfo11) | 是 | 退场页面信息。| 1265| to | [NavContentInfo](#navcontentinfo11) | 是 | 进场页面信息。| 1266| isInteractive<sup>12+</sup> | boolean | 否 | 是否为可交互转场动画。| 1267 1268### finishTransition 1269 1270finishTransition(): void; 1271 1272结束本次自定义转场动画,开发者需要主动触发该方法来结束本次转场,否则系统会在timeout的时间后结束本次转场。 1273 1274**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1275 1276**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1277 1278### cancelTransition<sup>12+</sup> 1279 1280cancelTransition?(): void; 1281 1282取消本次交互转场,恢复到页面跳转前的页面栈(不支持取消不可交互转场动画)。 1283 1284**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1285 1286**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1287 1288### updateTransition<sup>12+</sup> 1289 1290updateTransition?(progress: number): void; 1291 1292更新交互转场动画进度(不可交互动画不支持动画进度设置)。 1293 1294**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1295 1296**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1297 1298**参数:** 1299 1300| 参数名 | 类型 | 必填 | 说明 | 1301|------|------|------|-----| 1302| progress | number | 是 | 设置交互转场动画进度百分比。取值范围 0-1。| 1303 1304## NavigationInterception<sup>12+</sup> 1305 1306Navigation跳转拦截对象。 1307 1308**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1309 1310**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1311 1312| 名称 | 类型 | 必填 | 说明 | 1313| ---- | ----- | ----- | ---- | 1314| willShow | [InterceptionShowCallback](#interceptionshowcallback12) | 否 | 页面跳转前拦截,允许操作栈,在当前跳转中生效。| 1315| didShow | [InterceptionShowCallback](#interceptionshowcallback12) | 否 | 页面跳转后回调。在该回调中操作栈在下一次跳转中刷新。| 1316| modeChange | [InterceptionModeCallback](#interceptionmodecallback12) | 否 | Navigation单双栏显示状态发生变更时触发该回调。| 1317 1318### InterceptionShowCallback<sup>12+</sup> 1319 1320type InterceptionShowCallback = (from: NavDestinationContext|NavBar, to: NavDestinationContext|NavBar, operation: NavigationOperation, isAnimated: boolean) => void 1321 1322navigation页面跳转前和页面跳转后的拦截回调。 1323 1324**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1325 1326**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1327 1328| 参数名 | 类型 | 必填 | 说明 | 1329| ------ | ------ | ---- | ---------------- | 1330| from | [NavDestinationContext](ts-basic-components-navdestination.md#navdestinationcontext11) \|[NavBar](#navbar12) | 是 | 页面跳转之前的栈顶页面信息。参数值为navBar,则表示跳转前的页面为Navigation首页。 | 1331| to | [NavDestinationContext](ts-basic-components-navdestination.md#navdestinationcontext11) \|[NavBar](#navbar12) | 是 | 页面跳转之后的栈顶页面信息。参数值为navBar,则表示跳转的目标页面为Navigation首页。 | 1332| operation | [NavigationOperation](#navigationoperation11枚举说明) | 是 | 当前页面跳转类型。 | 1333| isAnimated | boolean | 是 | 页面跳转是否有动画。 | 1334 1335### InterceptionModeCallback<sup>12+</sup> 1336 1337type InterceptionModeCallback = (mode: NavigationMode) => void 1338 1339navigation单双栏显示状态发生变更时的拦截回调。 1340 1341**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1342 1343**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1344 1345| 参数名 | 类型 | 必填 | 说明 | 1346| ------ | ------ | ---- | ---------------- | 1347| mode | [NavigationMode](#navigationmode9枚举说明) | 是 | 导航栏的显示模式。 | 1348 1349## NavBar<sup>12+</sup> 1350 1351type NavBar = 'navBar' 1352 1353Navigation首页名字。 1354 1355**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1356 1357**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1358 1359| 类型 | 说明 | 1360| -------- | ---------------- | 1361| 'navBar' | Navigation首页。 | 1362 1363## NavigationMenuItem 1364 1365**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1366 1367| 名称 | 类型 | 必填 | 说明 | 1368| ------ | ------------- | ---- | --------------- | 1369| value | string \| [Resource<sup>14+<sup>](ts-types.md#resource) | 是 | API Version 9: 显示菜单栏单个选项的文本。<br> API Version 10: 不显示菜单栏单个选项的文本。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | 1370| icon | string \| [Resource<sup>14+<sup>](ts-types.md#resource) | 否 | 菜单栏单个选项的图标资源路径。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | 1371| isEnabled<sup>12+</sup> | boolean | 否 | 使能状态,默认使能(false未使能,true使能)。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | 1372| action | () => void | 否 | 当前选项被选中的事件回调。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | 1373| symbolIcon<sup>12+</sup> | [SymbolGlyphModifier](ts-universal-attributes-attribute-modifier.md) | 否 |菜单栏单个选项的symbol资源(优先级高于icon)。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | 1374 1375## ToolbarItem<sup>10+</sup> 1376 1377**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1378 1379**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1380 1381| 名称 | 类型 | 必填 | 说明 | 1382| ---------- | ---------------------------------------- | ---- | ---------------------------------------- | 1383| value | ResourceStr | 是 | 工具栏单个选项的显示文本。 | 1384| icon | ResourceStr | 否 | 工具栏单个选项的图标资源路径。 | 1385| action | () => void | 否 | 当前选项被选中的事件回调。 | 1386| status | [ToolbarItemStatus](#toolbaritemstatus10枚举说明) | 否 | 工具栏单个选项的状态。<br/>默认值:ToolbarItemStatus.NORMAL | 1387| activeIcon | ResourceStr | 否 | 工具栏单个选项处于ACTIVE态时的图标资源路径。 | 1388| symbolIcon<sup>12+</sup> | [SymbolGlyphModifier](ts-universal-attributes-attribute-modifier.md) | 否 | 工具栏单个选项的symbol资源(优先级高于icon)。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | 1389| activeSymbolIcon<sup>12+</sup> | [SymbolGlyphModifier](ts-universal-attributes-attribute-modifier.md) | 否 | 工具栏单个选项处于ACTIVE态时的symbol资源(优先级高于activeIcon)。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | 1390 1391## ToolbarItemStatus<sup>10+</sup>枚举说明 1392 1393**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1394 1395**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1396 1397| 名称 | 说明 | 1398| -------- | ------------------------------------------------------------ | 1399| NORMAL | 设置工具栏单个选项为NORMAL态,该选项显示默认样式,可以触发Hover,Press,Focus事件并显示对应的多态样式。 | 1400| DISABLED | 设置工具栏单个选项为DISABLED态, 该选项显示DISABLED态样式,并且不可交互。 | 1401| ACTIVE | 设置工具栏单个选项为ACTIVE态, 该选项通过点击事件可以将icon图标更新为activeIcon对应的图片资源。 | 1402 1403## NavigationTitleMode枚举说明 1404 1405**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1406 1407**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1408 1409| 名称 | 说明 | 1410| ---- | ------------------------------------------------------------ | 1411| Free | 当内容为满一屏的可滚动组件时,标题随着内容向上滚动而缩小(子标题的大小不变、淡出)。向下滚动内容到顶时则恢复原样。<br/>**说明:** <br/>标题随着内容滚动大小联动的动效在title设置为ResourceStr和NavigationCommonTitle时生效,设置成其余自定义节点类型时字体样式无法变化,下拉时只影响标题栏偏移。<br/>可滚动组件不满一屏时,如果想使用联动效果,就要使用滚动组件提供的[edgeEffect](ts-container-list.md#属性)接口将options参数设置为true。未滚动状态,标题栏高度与Full模式一致;滚动时,标题栏的最小高度与Mini模式一致。 | 1412| Mini | 固定为小标题模式。<br/>默认值:API version 12之前,只有主标题时,标题栏高度为56vp;同时有主标题和副标题时,标题栏高度为82vp。从API version 12开始,该模式下标题栏高度为56vp。 | 1413| Full | 固定为大标题模式。<br/>默认值:只有主标题时,标题栏高度为112vp;同时有主标题和副标题时,标题栏高度为138vp。 | 1414 1415## NavigationCommonTitle<sup>9+</sup> 1416 1417**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1418 1419**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1420 1421| 名称 | 类型 | 必填 | 说明 | 1422| ---- | ------ | ---- | ------ | 1423| main | string \| [Resource<sup>14+<sup>](ts-types.md#resource) | 是 | 设置主标题。 | 1424| sub | string \| [Resource<sup>14+<sup>](ts-types.md#resource) | 是 | 设置副标题。 | 1425 1426## NavigationCustomTitle<sup>9+</sup> 1427 1428**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1429 1430**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1431 1432| 名称 | 类型 | 必填 | 说明 | 1433| ------- | ---------------------------------------- | ---- | -------- | 1434| builder | [CustomBuilder](ts-types.md#custombuilder8) | 是 | 设置标题栏内容。 | 1435| height | [TitleHeight](ts-appendix-enums.md#titleheight9) \| [Length](ts-types.md#length) | 是 | 设置标题栏高度。 | 1436 1437## NavBarPosition<sup>9+</sup>枚举说明 1438 1439**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1440 1441**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1442 1443| 名称 | 说明 | 1444| ----- | -------------------------------- | 1445| Start | 双栏显示时,主列在主轴方向首部。 | 1446| End | 双栏显示时,主列在主轴方向尾部。 | 1447 1448## NavigationMode<sup>9+</sup>枚举说明 1449 1450**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1451 1452**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1453 1454| 名称 | 说明 | 1455| ----- | ------------------------------------------------------------ | 1456| Stack | 导航栏与内容区独立显示,相当于两个页面。 | 1457| Split | 导航栏与内容区分两栏显示。<br/>以下navBarWidthRange的值用[minNavBarWidth,maxNavBarWidth]表示<br/>1.当navBarWidth属性的值,在navBarWidthRange属性的值范围以外时,navBarWidth按如下规则显示:<br/>navBarWidth < minNavBarWidth时,navBarWidth修正为minNavBarWidth;<br/>navBarWidth > maxNavBarWidth,且组件宽度 - minContentWidth - 分割线宽度(1vp) > maxNavBarWidth时,navBarWidth修正为maxNavBarWidth;<br/>navBarWidth > maxNavBarWidth,且组件宽度 - minContentWidth - 分割线宽度(1vp) < minNavBarWidth时,navBarWidth修正为minNavBarWidth;<br/>navBarWidth > maxNavBarWidth,且组件宽度 - minContentWidth - 分割线宽度(1vp)在navBarWidthRange范围内,navBarWidth修正为组件宽度 - 分割线宽度(1vp) - minContentWidth。<br/>2.当navBarWidth属性的值,在navBarWidthRange属性的值范围以内时,navBarWidth按如下规则显示:<br/>minNavBarWidth + minContentWidth + 分割线宽度(1vp) >= 组件宽度时,navBarWidth修正为minNavBarWidth;<br/>minNavBarWidth + minContentWidth + 分割线宽度(1vp) < 组件宽度,且navBarWidth + minContentWidth + 分割线宽度(1vp) >= 组件宽度时,navBarWidth修正为组件宽度 - 分割线宽度(1vp) - minContentWidth;<br/>minNavBarWidth + minContentWidth + 分割线宽度(1vp) < 组件宽度,且navBarWidth + minContentWidth + 分割线宽度(1vp) < 组件宽度时,navBarWidth为设置的值。<br/>3.缩小组件尺寸时,先缩小内容区的尺寸至minContentWidth,然后再缩小导航栏的尺寸至minNavBarWidth。若继续缩小,先缩小内容区,内容区消失后再缩小导航栏。<br/>4.设置导航栏为固定尺寸时,若持续缩小组件尺寸,导航栏最后压缩显示。<br/>5.若只设置了navBarWidth属性,则导航栏宽度为navBarWidth,且分割线不可拖动。 | 1458| Auto | API version 9之前:窗口宽度>=520vp时,采用Split模式显示;窗口宽度<520vp时,采用Stack模式显示。<br/>API version 10及以上:窗口宽度>=600vp时,采用Split模式显示;窗口宽度<600vp时,采用Stack模式显示,600vp等于minNavBarWidth(240vp) + minContentWidth (360vp)。 | 1459 1460## NavigationOperation<sup>11+</sup>枚举说明 1461 1462**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1463 1464**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1465 1466| 名称 | 说明 | 1467|---------|------| 1468|PUSH | 本次转场为页面进场。| 1469|POP | 本次转场为页面退场。| 1470| REPLACE | 本次转场为页面替换。| 1471 1472## BarStyle<sup>12+</sup>枚举说明 1473 1474**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1475 1476**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1477 1478| 名称 | 说明 | 1479|---------|------| 1480|STANDARD | 标题栏与内容区采用上下布局。| 1481|STACK | 标题栏与内容区采用层叠布局,标题栏布局在内容区上层。| 1482 1483## NavigationTitleOptions<sup>11+</sup> 1484 1485**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1486 1487| 名称 | 类型 | 必填 | 说明 | 1488| ------ | ------------- | ---- | --------------- | 1489| backgroundColor | [ResourceColor](ts-types.md#resourcecolor) | 否 | 标题栏背景颜色,不设置时为系统默认颜色。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | 1490| backgroundBlurStyle | [BlurStyle](ts-universal-attributes-background.md#blurstyle9) | 否 | 标题栏背景模糊样式,不设置时关闭背景模糊效果。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | 1491| barStyle<sup>12+</sup> | [BarStyle](#barstyle12枚举说明) | 否 | 标题栏布局方式设置。<br/>默认值:BarStyle.STANDARD<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | 1492| paddingStart<sup>12+</sup> | [LengthMetrics](../js-apis-arkui-graphics.md#lengthmetrics12) | 否 | 标题栏起始端内间距。<br/>仅支持以下任一场景:<br/>1. 显示返回图标,即[hideBackButton](#hidebackbutton)为false;<br/>2. 使用非自定义标题,即[标题value](#title)类型为ResourceStr或NavigationCommonTitle。<br/>默认值:<br/>LengthMetrics.resource(`$r('sys.float.margin_left')`)。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | 1493| paddingEnd<sup>12+</sup> | [LengthMetrics](../js-apis-arkui-graphics.md#lengthmetrics12) | 否 | 标题栏结束端内间距。<br/>仅支持以下任一场景:<br/>1. 使用非自定义菜单,即[菜单value](#menus)为Array<NavigationMenuItem>;<br/>2. 没有右上角菜单,且使用非自定义标题,即[标题value](#title)类型为ResourceStr或NavigationCommonTitle。<br/>默认值:<br/>LengthMetrics.resource(`$r('sys.float.margin_right')`)。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | 1494| mainTitleModifier<sup>13+</sup> | [TextModifier](./ts-universal-attributes-attribute-modifier.md) | 否 | 主标题属性修改器。<br/>有如下几点使用规则:<br/>1. 通过Modifier设置的属性会覆盖系统默认的属性(如果Modifier设置了fontSize, maxFontSize, minFontSize任一属性,则系统设置的大小相关属性不生效,以开发者的设置为准);<br/>2. 不设该属性或者设置了异常值,则恢复系统默认设置;<br/>3. [Free](#navigationtitlemode枚举说明)模式下设置字体大小时,原有滑动改变标题大小的效果失效。<br/>**原子化服务API:** 从API version 13开始,该接口支持在原子化服务中使用。 | 1495| subTitleModifier<sup>13+</sup> | [TextModifier](./ts-universal-attributes-attribute-modifier.md) | 否 | 子标题属性修改器。<br/>有如下几点使用规则:<br/>1. 通过Modifier设置的属性会覆盖系统默认的属性(如果Modifier设置了fontSize, maxFontSize, minFontSize任一属性,则系统设置的大小相关属性不生效,以开发者的设置为准);<br/>2. 不设该属性或者设置了异常值,则恢复系统默认设置。<br/>**原子化服务API:** 从API version 13开始,该接口支持在原子化服务中使用。 | 1496| enableHoverMode<sup>14</sup> | boolean | 否 | 是否响应悬停态。<br/>使用规则:<br/>1. 需满足Navigation为全屏大小;<br/>2. 标题栏显示模式为[Free](#navigationtitlemode枚举说明)时或者标题栏布局方式为[STANDARD](#barstyle12枚举说明)时,此接口设置无效。<br/>默认值:false。<br/>**原子化服务API:** 从API version 14开始,该接口支持在原子化服务中使用。 | 1497 1498## NavigationToolbarOptions<sup>11+</sup> 1499 1500**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 1501 1502**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1503 1504| 名称 | 类型 | 必填 | 说明 | 1505| ------ | ------------- | ---- | --------------- | 1506| backgroundColor | [ResourceColor](ts-types.md#resourcecolor) | 否 | 工具栏背景颜色,不设置时为系统默认颜色。 | 1507| backgroundBlurStyle | [BlurStyle](ts-universal-attributes-background.md#blurstyle9) | 否 | 工具栏背景模糊样式,不设置时关闭背景模糊效果。 | 1508 1509## LaunchMode<sup>12+</sup>枚举说明 1510 1511**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1512 1513**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1514 1515| 名称 | 说明 | 1516| --------- | ------ | 1517| STANDARD | 系统默认的栈操作模式。<br/>push操作会将指定的NavDestination入栈;replace操作会将当前栈顶NavDestination替换。 | 1518| MOVE_TO_TOP_SINGLETON | 从栈底向栈顶查找,如果指定的名称已经存在,则将对应的NavDestination页面移到栈顶(replace操作会将最后的栈顶替换成指定的NavDestination),否则行为和STANDARD一致。 | 1519| POP_TO_SINGLETON | 从栈底向栈顶查找,如果指定的名称已经存在,则将其上方的NavDestination页面全部移除(replace操作会将最后的栈顶替换成指定的NavDestination),否则行为和STANDARD一致。 | 1520| NEW_INSTANCE | 创建新的NavDestination实例。与STANDARD模式相比,该方法不会复用栈中同名实例。 | 1521 1522## NavigationOptions<sup>12+</sup> 1523 1524**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 1525 1526**系统能力:** SystemCapability.ArkUI.ArkUI.Full 1527 1528| 名称 | 类型 | 必填 | 说明 | 1529| ------ | ------------- | ---- | --------------- | 1530| launchMode | [LaunchMode](#launchmode12枚举说明) | 否 | 页面栈的操作模式。<br/>默认值:LaunchMode.STANDARD | 1531| animated | boolean | 否 | 是否支持转场动画。<br/>默认值:true。 | 1532 1533## 示例 1534 1535示例效果请以真机为准。 1536 1537### 示例1 1538 1539该示例主要演示Navigation页面的布局。 1540 1541```ts 1542// xxx.ets 1543class A { 1544 text: string = '' 1545 num: number = 0 1546} 1547 1548@Entry 1549@Component 1550struct NavigationExample { 1551 private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 1552 @State currentIndex: number = 0 1553 1554 @Builder NavigationTitle() { 1555 Column() { 1556 Text('Title') 1557 .fontColor('#182431') 1558 .fontSize(30) 1559 .lineHeight(41) 1560 .fontWeight(700) 1561 Text('subtitle') 1562 .fontColor('#182431') 1563 .fontSize(14) 1564 .lineHeight(19) 1565 .opacity(0.4) 1566 .margin({ top: 2, bottom: 20 }) 1567 }.alignItems(HorizontalAlign.Start) 1568 } 1569 1570 @Builder NavigationMenus() { 1571 Row() { 1572 Image('resources/base/media/ic_public_add.svg') 1573 .width(24) 1574 .height(24) 1575 Image('resources/base/media/ic_public_add.svg') 1576 .width(24) 1577 .height(24) 1578 .margin({ left: 24 }) 1579 Image('common/ic_public_more.svg') 1580 .width(24) 1581 .height(24) 1582 .margin({ left: 24 }) 1583 } 1584 } 1585 1586 build() { 1587 Column() { 1588 Navigation() { 1589 TextInput({ placeholder: 'search...' }) 1590 .width('90%') 1591 .height(40) 1592 .backgroundColor('#FFFFFF') 1593 .margin({ top: 8 }) 1594 1595 List({ space: 12, initialIndex: 0 }) { 1596 ForEach(this.arr, (item: number) => { 1597 ListItem() { 1598 Text('' + item) 1599 .width('90%') 1600 .height(72) 1601 .backgroundColor('#FFFFFF') 1602 .borderRadius(24) 1603 .fontSize(16) 1604 .fontWeight(500) 1605 .textAlign(TextAlign.Center) 1606 } 1607 }, (item: number) => item.toString()) 1608 } 1609 .height(324) 1610 .width('100%') 1611 .margin({ top: 12, left: '10%' }) 1612 } 1613 .title(this.NavigationTitle) 1614 .menus(this.NavigationMenus) 1615 .titleMode(NavigationTitleMode.Full) 1616 .toolbarConfiguration([ 1617 { 1618 value: $r("app.string.navigation_toolbar_add"), 1619 icon: $r("app.media.ic_public_highlightsed") 1620 }, 1621 { 1622 value: $r("app.string.navigation_toolbar_app"), 1623 icon: $r("app.media.ic_public_highlights") 1624 }, 1625 { 1626 value: $r("app.string.navigation_toolbar_collect"), 1627 icon: $r("app.media.ic_public_highlights") 1628 } 1629 ]) 1630 .hideTitleBar(false) 1631 .hideToolBar(false) 1632 .onTitleModeChange((titleModel: NavigationTitleMode) => { 1633 console.info('titleMode' + titleModel) 1634 }) 1635 }.width('100%').height('100%').backgroundColor('#F1F3F5') 1636 } 1637} 1638``` 1639 1640 1641 1642 1643 1644### 示例2 1645 1646该示例主要演示NavPathStack中方法的使用及路由拦截。 1647 1648```ts 1649// Index.ets 1650 1651@Entry 1652@Component 1653struct NavigationExample { 1654 pageInfos: NavPathStack = new NavPathStack() 1655 isUseInterception: boolean = false; 1656 1657 registerInterception() { 1658 this.pageInfos.setInterception({ 1659 willShow: (from: NavDestinationContext | "navBar", to: NavDestinationContext | "navBar", 1660 operation: NavigationOperation, animated: boolean) => { 1661 if (!this.isUseInterception) { 1662 return; 1663 } 1664 if (typeof to === "string") { 1665 console.log("target page is navigation home"); 1666 return; 1667 } 1668 // redirect target page.Change pageTwo to pageOne. 1669 let target: NavDestinationContext = to as NavDestinationContext; 1670 if (target.pathInfo.name === 'pageTwo') { 1671 target.pathStack.pop(); 1672 target.pathStack.pushPathByName('pageOne', null); 1673 } 1674 }, 1675 didShow: (from: NavDestinationContext | "navBar", to: NavDestinationContext | "navBar", 1676 operation: NavigationOperation, isAnimated: boolean) => { 1677 if (!this.isUseInterception) { 1678 return; 1679 } 1680 if (typeof from === "string") { 1681 console.log("current transition is from navigation home"); 1682 } else { 1683 console.log(`current transition is from ${(from as NavDestinationContext).pathInfo.name}`) 1684 } 1685 if (typeof to === "string") { 1686 console.log("current transition to is navBar"); 1687 } else { 1688 console.log(`current transition is to ${(to as NavDestinationContext).pathInfo.name}`); 1689 } 1690 }, 1691 modeChange: (mode: NavigationMode) => { 1692 if (!this.isUseInterception) { 1693 return; 1694 } 1695 console.log(`current navigation mode is ${mode}`); 1696 } 1697 }) 1698 } 1699 1700 build() { 1701 Navigation(this.pageInfos) { 1702 Column() { 1703 Button('pushPath', { stateEffect: true, type: ButtonType.Capsule }) 1704 .width('80%') 1705 .height(40) 1706 .margin(20) 1707 .onClick(() => { 1708 this.pageInfos.pushPath({ name: 'pageOne' }) //将name指定的NavDestination页面信息入栈 1709 }) 1710 Button('use interception', { stateEffect: true, type: ButtonType.Capsule }) 1711 .width('80%') 1712 .height(40) 1713 .margin(20) 1714 .onClick(() => { 1715 this.isUseInterception = !this.isUseInterception; 1716 if (this.isUseInterception) { 1717 this.registerInterception(); 1718 } else { 1719 this.pageInfos.setInterception(undefined); 1720 } 1721 }) 1722 } 1723 }.title('NavIndex') 1724 } 1725} 1726``` 1727```ts 1728// PageOne.ets 1729class TmpClass{ 1730 count:number=10 1731} 1732 1733@Builder 1734export function PageOneBuilder(name: string, param: Object) { 1735 PageOne() 1736} 1737 1738@Component 1739export struct PageOne { 1740 1741 pageInfos: NavPathStack = new NavPathStack() 1742 1743 build() { 1744 NavDestination() { 1745 Column() { 1746 Button('pushPathByName', { stateEffect: true, type: ButtonType.Capsule }) 1747 .width('80%') 1748 .height(40) 1749 .margin(20) 1750 .onClick(() => { 1751 let tmp = new TmpClass() 1752 this.pageInfos.pushPathByName('pageTwo', tmp) //将name指定的NavDestination页面信息入栈,传递的数据为param 1753 }) 1754 Button('singletonLaunchMode', { stateEffect: true, type: ButtonType.Capsule }) 1755 .width('80%') 1756 .height(40) 1757 .margin(20) 1758 .onClick(() => { 1759 this.pageInfos.pushPath({ name: 'pageOne' }, { launchMode: LaunchMode.MOVE_TO_TOP_SINGLETON }) //从栈底向栈顶查找,如果指定的名称已经存在,则将对应的NavDestination页面移到栈顶 1760 }) 1761 Button('popToname', { stateEffect: true, type: ButtonType.Capsule }) 1762 .width('80%') 1763 .height(40) 1764 .margin(20) 1765 .onClick(() => { 1766 this.pageInfos.popToName('pageTwo') //回退路由栈到第一个名为name的NavDestination页面 1767 console.log('popToName' + JSON.stringify(this.pageInfos), '返回值' + JSON.stringify(this.pageInfos.popToName('pageTwo'))) 1768 }) 1769 Button('popToIndex', { stateEffect: true, type: ButtonType.Capsule }) 1770 .width('80%') 1771 .height(40) 1772 .margin(20) 1773 .onClick(() => { 1774 this.pageInfos.popToIndex(1) // 回退路由栈到index指定的NavDestination页面 1775 console.log('popToIndex' + JSON.stringify(this.pageInfos)) 1776 }) 1777 Button('moveToTop', { stateEffect: true, type: ButtonType.Capsule }) 1778 .width('80%') 1779 .height(40) 1780 .margin(20) 1781 .onClick(() => { 1782 this.pageInfos.moveToTop('pageTwo') // 将第一个名为name的NavDestination页面移到栈顶 1783 console.log('moveToTop' + JSON.stringify(this.pageInfos), '返回值' + JSON.stringify(this.pageInfos.moveToTop('pageTwo'))) 1784 }) 1785 Button('moveIndexToTop', { stateEffect: true, type: ButtonType.Capsule }) 1786 .width('80%') 1787 .height(40) 1788 .margin(20) 1789 .onClick(() => { 1790 this.pageInfos.moveIndexToTop(1) // 将index指定的NavDestination页面移到栈顶 1791 console.log('moveIndexToTop' + JSON.stringify(this.pageInfos)) 1792 }) 1793 Button('clear', { stateEffect: true, type: ButtonType.Capsule }) 1794 .width('80%') 1795 .height(40) 1796 .margin(20) 1797 .onClick(() => { 1798 this.pageInfos.clear() //清除栈中所有页面 1799 }) 1800 Button('get', { stateEffect: true, type: ButtonType.Capsule }) 1801 .width('80%') 1802 .height(40) 1803 .margin(20) 1804 .onClick(() => { 1805 console.log('-------------------') 1806 console.log('获取栈中所有NavDestination页面的名称', JSON.stringify(this.pageInfos.getAllPathName())) 1807 console.log('获取index指定的NavDestination页面的参数信息', JSON.stringify(this.pageInfos.getParamByIndex(1))) 1808 console.log('获取全部名为name的NavDestination页面的参数信息', JSON.stringify(this.pageInfos.getParamByName('pageTwo'))) 1809 console.log('获取全部名为name的NavDestination页面的位置索引', JSON.stringify(this.pageInfos.getIndexByName('pageOne'))) 1810 console.log('获取栈大小', JSON.stringify(this.pageInfos.size())) 1811 }) 1812 }.width('100%').height('100%') 1813 }.title('pageOne') 1814 .onBackPressed(() => { 1815 const popDestinationInfo = this.pageInfos.pop() // 弹出路由栈栈顶元素 1816 console.log('pop' + '返回值' + JSON.stringify(popDestinationInfo)) 1817 return true 1818 }).onReady((context: NavDestinationContext) => { 1819 this.pageInfos = context.pathStack 1820 }) 1821 } 1822} 1823``` 1824```ts 1825// PageTwo.ets 1826@Builder 1827export function PageTwoBuilder(name: string, param: Object) { 1828 PageTwo() 1829} 1830 1831@Component 1832export struct PageTwo { 1833 pathStack: NavPathStack = new NavPathStack() 1834 1835 private menuItems: Array<NavigationMenuItem> = [ 1836 { 1837 value: "1", 1838 icon: 'resources/base/media/undo.svg', 1839 }, 1840 { 1841 value: "2", 1842 icon: 'resources/base/media/redo.svg', 1843 isEnabled: false, 1844 }, 1845 { 1846 value: "3", 1847 icon: 'resources/base/media/ic_public_ok.svg', 1848 isEnabled: true, 1849 } 1850 ] 1851 1852 build() { 1853 NavDestination() { 1854 Column() { 1855 Button('pushPathByName', { stateEffect: true, type: ButtonType.Capsule }) 1856 .width('80%') 1857 .height(40) 1858 .margin(20) 1859 .onClick(() => { 1860 this.pathStack.pushPathByName('pageOne', null) 1861 }) 1862 }.width('100%').height('100%') 1863 }.title('pageTwo') 1864 .menus(this.menuItems) 1865 .onBackPressed(() => { 1866 this.pathStack.pop() 1867 return true 1868 }) 1869 .onReady((context: NavDestinationContext) => { 1870 this.pathStack = context.pathStack; 1871 console.log("current page config info is " + JSON.stringify(context.getConfigInRouteMap())) 1872 }) 1873 } 1874} 1875``` 1876 1877```json 1878// 工程配置文件module.json5中配置 {"routerMap": "$profile:route_map"} 1879// route_map.json 1880{ 1881 "routerMap": [ 1882 { 1883 "name": "pageOne", 1884 "pageSourceFile": "src/main/ets/pages/PageOne.ets", 1885 "buildFunction": "PageOneBuilder", 1886 "data": { 1887 "description": "this is pageOne" 1888 } 1889 }, 1890 { 1891 "name": "pageTwo", 1892 "pageSourceFile": "src/main/ets/pages/PageTwo.ets", 1893 "buildFunction": "PageTwoBuilder" 1894 } 1895 ] 1896} 1897``` 1898 1899 1900### 示例3 1901 1902该示例主要演示设置每个NavDestination子页面的自定义转场动画及可交互转场动画。 1903 1904```ts 1905// Index.ets 1906import { CustomTransition, AnimateCallback } from './CustomNavigationUtils' 1907 1908@Entry 1909@Component 1910struct NavigationExample { 1911 pageInfos: NavPathStack = new NavPathStack(); 1912 1913 aboutToAppear() { 1914 if (this.pageInfos === undefined) { 1915 this.pageInfos = new NavPathStack(); 1916 } 1917 this.pageInfos.pushPath({ name: 'pageOne', param: CustomTransition.getInstance().getAnimationId() }); 1918 } 1919 1920 build() { 1921 Navigation(this.pageInfos) { 1922 } 1923 .title('NavIndex') 1924 .hideNavBar(true) 1925 .customNavContentTransition((from: NavContentInfo, to: NavContentInfo, operation: NavigationOperation) => { 1926 if (from.mode == NavDestinationMode.DIALOG || to.mode == NavDestinationMode.DIALOG) { 1927 return undefined; 1928 } 1929 1930 // 首页不进行自定义动画 1931 if (from.index === -1 || to.index === -1) { 1932 return undefined; 1933 } 1934 1935 CustomTransition.getInstance().operation = operation; 1936 if (CustomTransition.getInstance().interactive) { 1937 let customAnimation: NavigationAnimatedTransition = { 1938 onTransitionEnd: (isSuccess: boolean) => { 1939 console.log("===== current transition is " + isSuccess); 1940 CustomTransition.getInstance().recoverState(); 1941 CustomTransition.getInstance().proxy = undefined; 1942 }, 1943 transition: (transitionProxy: NavigationTransitionProxy) => { 1944 CustomTransition.getInstance().proxy = transitionProxy; 1945 let targetIndex: string | undefined = operation == NavigationOperation.PUSH ? 1946 (to.navDestinationId) : (from.navDestinationId); 1947 if (targetIndex) { 1948 CustomTransition.getInstance().fireInteractiveAnimation(targetIndex, operation); 1949 } 1950 }, 1951 isInteractive: CustomTransition.getInstance().interactive 1952 } 1953 return customAnimation; 1954 } 1955 let customAnimation: NavigationAnimatedTransition = { 1956 onTransitionEnd: (isSuccess: boolean)=>{ 1957 console.log(`current transition result is ${isSuccess}`) 1958 }, 1959 timeout: 7000, 1960 // 转场开始时系统调用该方法,并传入转场上下文代理对象 1961 transition: (transitionProxy: NavigationTransitionProxy) => { 1962 if (!from.navDestinationId || !to.navDestinationId) { 1963 return; 1964 } 1965 // 从封装类CustomTransition中根据子页面的序列获取对应的转场动画回调 1966 let fromParam: AnimateCallback = CustomTransition.getInstance().getAnimateParam(from.navDestinationId); 1967 let toParam: AnimateCallback = CustomTransition.getInstance().getAnimateParam(to.navDestinationId); 1968 if (operation == NavigationOperation.PUSH) { 1969 if (toParam.start) { 1970 toParam.start(true, false); 1971 } 1972 animateTo({ 1973 duration: 500, onFinish: () => { 1974 transitionProxy.finishTransition(); 1975 } 1976 }, () => { 1977 if (toParam.finish) { 1978 toParam.finish(true, false); 1979 } 1980 }) 1981 } else { 1982 if (fromParam.start) { 1983 fromParam.start(true, true); 1984 } 1985 animateTo({ 1986 duration: 500, onFinish: () => { 1987 transitionProxy.finishTransition(); 1988 } 1989 }, () => { 1990 if (fromParam.finish) { 1991 fromParam.finish(true, true); 1992 } 1993 }) 1994 } 1995 } 1996 }; 1997 return customAnimation; 1998 }) 1999 } 2000} 2001``` 2002 2003```ts 2004// PageOne.ets 2005import {CustomTransition} from './CustomNavigationUtils'; 2006 2007@Builder 2008export function PageOneBuilder(name: string, param: Object) { 2009 PageOne() 2010} 2011 2012@Component 2013export struct PageOne { 2014 pageInfos: NavPathStack = new NavPathStack(); 2015 @State translateX: string = '0'; 2016 pageId: string = ''; 2017 rectWidth: number = 0; 2018 interactive: boolean = false; 2019 2020 registerCallback() { 2021 CustomTransition.getInstance().registerNavParam(this.pageId, (isPush: boolean, isExit: boolean) => { 2022 if (isPush) { 2023 this.translateX = '100%'; 2024 } else { 2025 this.translateX = '0'; 2026 } 2027 }, (isPush: boolean, isExit: boolean) => { 2028 if (isPush) { 2029 this.translateX = '0'; 2030 } else { 2031 this.translateX = '100%'; 2032 } 2033 }, (isPush: boolean, isExit: boolean) => { 2034 this.translateX = '0'; 2035 }, (operation: NavigationOperation) => { 2036 if (operation == NavigationOperation.PUSH) { 2037 this.translateX = '100%'; 2038 animateTo({ 2039 duration: 1000, 2040 onFinish: () => { 2041 this.translateX = '0'; 2042 } 2043 }, () => { 2044 this.translateX = '0'; 2045 }) 2046 } else { 2047 this.translateX = '0'; 2048 animateTo({ 2049 duration: 1000, 2050 onFinish: () => { 2051 this.translateX = '0'; 2052 } 2053 }, () => { 2054 this.translateX = '100%'; 2055 }) 2056 } 2057 }, 200); 2058 } 2059 2060 build() { 2061 NavDestination() { 2062 Column() { 2063 Button(`setInteractive`) 2064 .onClick(() => { 2065 CustomTransition.getInstance().interactive = !CustomTransition.getInstance().interactive; 2066 this.interactive = CustomTransition.getInstance().interactive; 2067 }) 2068 2069 Button('pushPathByName', { stateEffect: true, type: ButtonType.Capsule }) 2070 .width('80%') 2071 .height(40) 2072 .margin(20) 2073 .onClick(() => { 2074 //将name指定的NavDestination页面信息入栈,传递的数据为param 2075 this.pageInfos.pushDestinationByName('pageTwo', CustomTransition.getInstance().getAnimationId()); 2076 }) 2077 } 2078 .size({ width: '100%', height: '100%' }) 2079 } 2080 .title('pageOne') 2081 .onDisAppear(() => { 2082 CustomTransition.getInstance().unRegisterNavParam(this.pageId); 2083 }) 2084 .onReady((context: NavDestinationContext) => { 2085 this.pageInfos = context.pathStack; 2086 if (context.navDestinationId) { 2087 this.pageId = context.navDestinationId; 2088 this.registerCallback(); 2089 } 2090 }) 2091 .translate({ x: this.translateX }) 2092 .backgroundColor('#F1F3F5') 2093 .gesture(PanGesture() 2094 .onActionStart((event: GestureEvent) => { 2095 this.rectWidth = event.target.area.width as number; 2096 if (event.offsetX < 0) { 2097 this.pageInfos.pushPath({ name: 'pageTwo', param: CustomTransition.getInstance().getAnimationId() }); 2098 } else { 2099 this.pageInfos.pop(); 2100 } 2101 }) 2102 .onActionUpdate((event: GestureEvent) => { 2103 let rate = event.fingerList[0].localX / this.rectWidth; 2104 CustomTransition.getInstance().updateProgress(rate); 2105 }) 2106 .onActionEnd((event: GestureEvent) => { 2107 let rate: number = event.fingerList[0].localX / this.rectWidth; 2108 CustomTransition.getInstance().finishInteractiveAnimation(rate); 2109 })) 2110 } 2111} 2112``` 2113```ts 2114// PageTwo.ets 2115import {CustomTransition} from './CustomNavigationUtils' 2116 2117@Builder 2118export function PageTwoBuilder(name: string, param: Object) { 2119 PageTwo({param: param as number}) 2120} 2121 2122@Component 2123export struct PageTwo { 2124 pageInfos: NavPathStack = new NavPathStack(); 2125 @State translateX: string = '0'; 2126 pageId: string = ''; 2127 rectWidth: number = 0; 2128 param: number = 0; 2129 2130 registerCallback() { 2131 CustomTransition.getInstance().registerNavParam(this.pageId, (isPush: boolean, isExit: boolean)=>{ 2132 if (isPush) { 2133 this.translateX = '100%' 2134 } else { 2135 this.translateX = '0'; 2136 } 2137 }, (isPush: boolean, isExit: boolean)=>{ 2138 if (isPush) { 2139 this.translateX = '0'; 2140 } else { 2141 this.translateX = '100%' 2142 } 2143 }, (isPush: boolean, isExit: boolean) => { 2144 this.translateX = '0'; 2145 }, (operation: NavigationOperation)=>{ 2146 if (operation == NavigationOperation.PUSH) { 2147 this.translateX = '100%'; 2148 animateTo({duration: 500, onFinish: ()=>{ 2149 this.translateX = '0'; 2150 }}, ()=>{ 2151 this.translateX = '0' 2152 }) 2153 } else { 2154 this.translateX = '0'; 2155 animateTo({duration: 500, onFinish: ()=>{ 2156 this.translateX = "0" 2157 }}, ()=>{ 2158 this.translateX = '100%'; 2159 }) 2160 } 2161 }, 2000) 2162 } 2163 2164 build() { 2165 NavDestination() { 2166 Column() { 2167 Button('pushPathByName', { stateEffect: true, type: ButtonType.Capsule }) 2168 .width('80%') 2169 .height(40) 2170 .margin(20) 2171 .onClick(() => { 2172 //将name指定的NavDestination页面信息入栈,传递的数据为param 2173 this.pageInfos.pushPath({name:'pageOne', param: CustomTransition.getInstance().getAnimationId()}) 2174 }) 2175 } 2176 .size({ width: '100%', height: '100%' }) 2177 } 2178 .title('pageTwo') 2179 .gesture(PanGesture() 2180 .onActionStart((event: GestureEvent)=> { 2181 this.rectWidth = event.target.area.width as number; 2182 if (event.offsetX < 0) { 2183 this.pageInfos.pushPath({ name: 'pageOne', param: CustomTransition.getInstance().getAnimationId() }); 2184 } else { 2185 this.pageInfos.pop(); 2186 } 2187 }) 2188 .onActionUpdate((event: GestureEvent) => { 2189 let rate = event.fingerList[0].localX / this.rectWidth; 2190 CustomTransition.getInstance().updateProgress(rate); 2191 }) 2192 .onActionEnd((event: GestureEvent)=> { 2193 let rate = event.fingerList[0].localX / this.rectWidth; 2194 CustomTransition.getInstance().finishInteractiveAnimation(rate); 2195 })) 2196 .onAppear(() => { 2197 this.registerCallback(); 2198 }) 2199 .onDisAppear(()=>{ 2200 CustomTransition.getInstance().unRegisterNavParam(this.pageId); 2201 }) 2202 .onReady((context: NavDestinationContext) => { 2203 this.pageInfos = context.pathStack; 2204 if (context.navDestinationId) { 2205 this.pageId = context.navDestinationId; 2206 this.registerCallback(); 2207 } 2208 }) 2209 .translate({x: this.translateX}) 2210 .backgroundColor(Color.Yellow) 2211 } 2212} 2213``` 2214```ts 2215// CustomNavigationUtils.ets 2216// 自定义接口,用来保存某个页面相关的转场动画回调和参数 2217export interface AnimateCallback { 2218 finish: ((isPush: boolean, isExit: boolean) => void | undefined) | undefined; 2219 start: ((isPush: boolean, isExit: boolean) => void | undefined) | undefined; 2220 onFinish: ((isPush: boolean, isExit: boolean) => void | undefined) | undefined; 2221 interactive: ((operation: NavigationOperation) => void | undefined) | undefined; 2222 timeout: (number | undefined) | undefined; 2223} 2224const customTransitionMap: Map<string, AnimateCallback> = new Map(); 2225 2226export class CustomTransition { 2227 static delegate = new CustomTransition(); 2228 interactive: boolean = false; 2229 proxy: NavigationTransitionProxy| undefined = undefined; 2230 private animationId: number = 0; 2231 operation: NavigationOperation = NavigationOperation.PUSH 2232 2233 static getInstance() { 2234 return CustomTransition.delegate; 2235 } 2236 2237 /* 注册某个页面的动画回调 2238 * name: 注册页面的唯一id 2239 * startCallback:用来设置动画开始时页面的状态 2240 * endCallback:用来设置动画结束时页面的状态 2241 * onFinish:用来执行动画结束后页面的其他操作 2242 * interactiveCallback: 注册的可交互转场的动效 2243 * timeout:转场结束的超时时间 2244 */ 2245 registerNavParam(name: string, startCallback: (operation: boolean, isExit: boolean) => void, 2246 endCallback:(operation: boolean, isExit: boolean) => void, 2247 onFinish: (operation: boolean, isExit: boolean) => void, 2248 interactiveCallback: (operation: NavigationOperation) =>void, 2249 timeout: number): void { 2250 if (customTransitionMap.has(name)) { 2251 let param = customTransitionMap.get(name); 2252 if (param != undefined) { 2253 param.start = startCallback; 2254 param.finish = endCallback; 2255 param.timeout = timeout; 2256 param.onFinish = onFinish; 2257 param.interactive = interactiveCallback; 2258 return; 2259 } 2260 } 2261 let params: AnimateCallback = {timeout: timeout, start: startCallback, finish: endCallback, onFinish: onFinish, 2262 interactive: interactiveCallback}; 2263 customTransitionMap.set(name, params); 2264 } 2265 2266 getAnimationId() { 2267 return Date.now(); 2268 } 2269 2270 unRegisterNavParam(name: string): void { 2271 customTransitionMap.delete(name); 2272 } 2273 2274 fireInteractiveAnimation(id: string, operation: NavigationOperation) { 2275 let animation = customTransitionMap.get(id)?.interactive; 2276 if (!animation) { 2277 return; 2278 } 2279 animation(operation); 2280 } 2281 2282 updateProgress(progress: number) { 2283 if (!this.proxy?.updateTransition) { 2284 return; 2285 } 2286 progress = this.operation == NavigationOperation.PUSH ? 1 - progress : progress; 2287 this.proxy?.updateTransition(progress); 2288 } 2289 2290 cancelTransition() { 2291 if (this.proxy?.cancelTransition) { 2292 this.proxy.cancelTransition(); 2293 } 2294 } 2295 2296 recoverState() { 2297 if (!this.proxy?.from.navDestinationId || !this.proxy?.to.navDestinationId) { 2298 return; 2299 } 2300 let fromParam = customTransitionMap.get(this.proxy.from.navDestinationId); 2301 if (fromParam?.onFinish) { 2302 fromParam.onFinish(false, false); 2303 } 2304 let toParam = customTransitionMap.get(this.proxy?.to.navDestinationId); 2305 if (toParam?.onFinish) { 2306 toParam.onFinish(true, true); 2307 } 2308 } 2309 2310 finishTransition() { 2311 this.proxy?.finishTransition(); 2312 } 2313 2314 finishInteractiveAnimation(rate: number) { 2315 if (this.operation == NavigationOperation.PUSH) { 2316 if (rate > 0.5) { 2317 if (this.proxy?.cancelTransition) { 2318 this.proxy.cancelTransition(); 2319 } 2320 } else { 2321 this.proxy?.finishTransition(); 2322 } 2323 } else { 2324 if (rate > 0.5) { 2325 this.proxy?.finishTransition(); 2326 } else { 2327 if (this.proxy?.cancelTransition) { 2328 this.proxy.cancelTransition(); 2329 } 2330 } 2331 } 2332 } 2333 2334 getAnimateParam(name: string): AnimateCallback { 2335 let result: AnimateCallback = { 2336 start: customTransitionMap.get(name)?.start, 2337 finish: customTransitionMap.get(name)?.finish, 2338 timeout: customTransitionMap.get(name)?.timeout, 2339 onFinish: customTransitionMap.get(name)?.onFinish, 2340 interactive: customTransitionMap.get(name)?.interactive, 2341 }; 2342 return result; 2343 } 2344} 2345``` 2346```json 2347// 工程配置文件module.json5中配置 {"routerMap": "$profile:route_map"} 2348// route_map.json 2349{ 2350 "routerMap": [ 2351 { 2352 "name": "pageOne", 2353 "pageSourceFile": "src/main/ets/pages/PageOne.ets", 2354 "buildFunction": "PageOneBuilder", 2355 "data": { 2356 "description": "this is pageOne" 2357 } 2358 }, 2359 { 2360 "name": "pageTwo", 2361 "pageSourceFile": "src/main/ets/pages/PageTwo.ets", 2362 "buildFunction": "PageTwoBuilder" 2363 } 2364 ] 2365} 2366``` 2367 2368 2369### 示例4 2370 2371该示例主要演示Navigation带参返回。 2372 2373```ts 2374// Index.ets 2375 2376@Entry 2377@Component 2378struct NavigationExample { 2379 pageInfo: NavPathStack = new NavPathStack() 2380 2381 build() { 2382 Navigation(this.pageInfo) { 2383 Column() { 2384 Button('StartTest', { stateEffect: true, type: ButtonType.Capsule }) 2385 .width('80%') 2386 .height(40) 2387 .margin(20) 2388 .onClick(() => { 2389 this.pageInfo.pushPath({ name: 'pageOne' }); // 将name指定的NavDestination页面信息入栈。 2390 }) 2391 } 2392 }.title('NavIndex') 2393 } 2394} 2395``` 2396```ts 2397// PageOne.ets 2398import { BusinessError } from '@kit.BasicServicesKit'; 2399 2400class TmpClass{ 2401 count:number = 10 2402} 2403 2404class ParamWithOp { 2405 operation: number = 1 2406 count: number = 10 2407} 2408 2409@Builder 2410export function PageOneBuilder(name: string, param: Object) { 2411 PageOne() 2412} 2413 2414@Component 2415export struct PageOne { 2416 pageInfo: NavPathStack = new NavPathStack(); 2417 @State message: string = 'Hello World' 2418 2419 build() { 2420 NavDestination() { 2421 Column() { 2422 Text(this.message) 2423 .width('80%') 2424 .height(50) 2425 .margin(10) 2426 2427 Button('pushPath', { stateEffect: true, type: ButtonType.Capsule }) 2428 .width('80%') 2429 .height(40) 2430 .margin(10) 2431 .onClick(()=>{ 2432 this.pageInfo.pushPath({name: 'pageTwo', param: new ParamWithOp(), onPop: (popInfo: PopInfo)=>{ 2433 this.message = '[pushPath]last page is: ' + popInfo.info.name + ', result: ' + JSON.stringify(popInfo.result); 2434 }}); // 将name指定的NavDestination页面信息入栈,传递的数据为param,添加接收处理结果的onPop回调。 2435 }) 2436 2437 Button('pushPathByName', { stateEffect: true, type: ButtonType.Capsule }) 2438 .width('80%') 2439 .height(40) 2440 .margin(10) 2441 .onClick(() => { 2442 let tmp = new TmpClass() 2443 this.pageInfo.pushPathByName('pageTwo', tmp, (popInfo)=>{ 2444 this.message = '[pushPathByName]last page is: ' + popInfo.info.name + ', result: ' + JSON.stringify(popInfo.result); 2445 }); // 将name指定的NavDestination页面信息入栈,传递的数据为param,添加接收处理结果的onPop回调。 2446 }) 2447 2448 Button('pushDestination', { stateEffect: true, type: ButtonType.Capsule }) 2449 .width('80%') 2450 .height(40) 2451 .margin(10) 2452 .onClick(()=>{ 2453 let tmp = new TmpClass() 2454 // 将name指定的NavDestination页面信息入栈,传递的数据为param,添加接收处理结果的onPop回调。 2455 this.pageInfo.pushDestination({name: 'pageTwo', param: new ParamWithOp(), onPop: (popInfo: PopInfo)=>{ 2456 this.message = '[pushDestination]last page is: ' + popInfo.info.name + ', result: ' + JSON.stringify(popInfo.result); 2457 }}).catch((error: BusinessError)=>{ 2458 console.error(`[pushDestination]failed, error code = ${error.code}, error.message = ${error.message}.`); 2459 }).then(()=>{ 2460 console.error('[pushDestination]success.'); 2461 }); 2462 }) 2463 2464 Button('pushDestinationByName', { stateEffect: true, type: ButtonType.Capsule }) 2465 .width('80%') 2466 .height(40) 2467 .margin(10) 2468 .onClick(()=>{ 2469 let tmp = new TmpClass() 2470 // 将name指定的NavDestination页面信息入栈,传递的数据为param,添加接收处理结果的onPop回调。 2471 this.pageInfo.pushDestinationByName('pageTwo', tmp, (popInfo)=>{ 2472 this.message = '[pushDestinationByName]last page is: ' + popInfo.info.name + ', result: ' + JSON.stringify(popInfo.result); 2473 }).catch((error: BusinessError)=>{ 2474 console.error(`[pushDestinationByName]failed, error code = ${error.code}, error.message = ${error.message}.`); 2475 }).then(()=>{ 2476 console.error('[pushDestinationByName]success.'); 2477 }); 2478 }) 2479 2480 Button('pushPathWithoutOnPop', { stateEffect: true, type: ButtonType.Capsule }) 2481 .width('80%') 2482 .height(40) 2483 .margin(10) 2484 .onClick(()=>{ 2485 this.pageInfo.pushPath({name: 'pageTwo', param: new ParamWithOp()}); // 将name指定的NavDestination页面信息入栈。 2486 }) 2487 2488 Button('pushPathByNameWithoutOnPop', { stateEffect: true, type: ButtonType.Capsule }) 2489 .width('80%') 2490 .height(40) 2491 .margin(10) 2492 .onClick(() => { 2493 let tmp = new TmpClass() 2494 this.pageInfo.pushPathByName('pageTwo', tmp); // 将name指定的NavDestination页面信息入栈,传递的数据为param。 2495 }) 2496 2497 Button('pushDestinationWithoutOnPop', { stateEffect: true, type: ButtonType.Capsule }) 2498 .width('80%') 2499 .height(40) 2500 .margin(10) 2501 .onClick(()=>{ 2502 let tmp = new TmpClass() 2503 // 将name指定的NavDestination页面信息入栈,传递的数据为param,添加接收处理结果的onPop回调。 2504 this.pageInfo.pushDestination({name: 'pageTwo', param: new ParamWithOp()}) 2505 .catch((error: BusinessError)=>{ 2506 console.error(`[pushDestinationWithoutOnPop]failed, error code = ${error.code}, error.message = ${error.message}.`); 2507 }).then(()=>{ 2508 console.error('[pushDestinationWithoutOnPop]success.'); 2509 }); 2510 }) 2511 2512 Button('pushDestinationByNameWithoutOnPop', { stateEffect: true, type: ButtonType.Capsule }) 2513 .width('80%') 2514 .height(40) 2515 .margin(10) 2516 .onClick(() => { 2517 let tmp = new TmpClass() 2518 // 将name指定的NavDestination页面信息入栈,传递的数据为param。 2519 this.pageInfo.pushDestinationByName('pageTwo', tmp) 2520 .catch((error: BusinessError)=>{ 2521 console.error(`[pushDestinationByNameWithoutOnPop]failed, error code = ${error.code}, error.message = ${error.message}.`); 2522 }).then(()=>{ 2523 console.error('[pushDestinationByNameWithoutOnPop]success.'); 2524 }); 2525 }) 2526 2527 Button('clear', { stateEffect: true, type: ButtonType.Capsule }) 2528 .width('80%') 2529 .height(40) 2530 .margin(10) 2531 .onClick(() => { 2532 this.pageInfo.clear(); // 清除栈中所有页面。 2533 }) 2534 }.width('100%').height('100%') 2535 }.title('pageOne') 2536 .onBackPressed(() => { 2537 this.pageInfo.pop({number: 1}) // 弹出路由栈栈顶元素。 2538 return true 2539 }).onReady((context: NavDestinationContext) => { 2540 this.pageInfo = context.pathStack; 2541 }) 2542 } 2543} 2544``` 2545```ts 2546// PageTwo.ets 2547 2548class resultClass { 2549 constructor(count: number) { 2550 this.count = count; 2551 } 2552 count: number = 10 2553} 2554 2555@Builder 2556export function PageTwoBuilder() { 2557 PageTwo() 2558} 2559 2560@Component 2561export struct PageTwo { 2562 pathStack: NavPathStack = new NavPathStack() 2563 2564 build() { 2565 NavDestination() { 2566 Column() { 2567 Button('pop', { stateEffect: true, type: ButtonType.Capsule }) 2568 .width('80%') 2569 .height(40) 2570 .margin(20) 2571 .onClick(() => { 2572 this.pathStack.pop(new resultClass(1)); // 回退到上一个页面,将处理结果传入push的onPop回调中。 2573 }) 2574 2575 Button('popToName', { stateEffect: true, type: ButtonType.Capsule }) 2576 .width('80%') 2577 .height(40) 2578 .margin(20) 2579 .onClick(() => { 2580 this.pathStack.popToName('pageOne', new resultClass(11)); // 将第一个名为name的NavDestination页面移到栈顶,将处理结果传入push的onPop回调中。 2581 }) 2582 2583 Button('popToIndex', { stateEffect: true, type: ButtonType.Capsule }) 2584 .width('80%') 2585 .height(40) 2586 .margin(20) 2587 .onClick(() => { 2588 this.pathStack.popToIndex(0, new resultClass(111)); // 将index指定的NavDestination页面移到栈顶,将处理结果传入push的onPop回调中。 2589 }) 2590 2591 Button('popWithoutResult', { stateEffect: true, type: ButtonType.Capsule }) 2592 .width('80%') 2593 .height(40) 2594 .margin(20) 2595 .onClick(() => { 2596 this.pathStack.pop(); 2597 }) 2598 2599 Button('popToNameWithoutResult', { stateEffect: true, type: ButtonType.Capsule }) 2600 .width('80%') 2601 .height(40) 2602 .margin(20) 2603 .onClick(() => { 2604 this.pathStack.popToName('pageOne'); 2605 }) 2606 2607 Button('popToIndexWithoutResult', { stateEffect: true, type: ButtonType.Capsule }) 2608 .width('80%') 2609 .height(40) 2610 .margin(20) 2611 .onClick(() => { 2612 this.pathStack.popToIndex(0); 2613 }) 2614 }.width('100%').height('100%') 2615 }.title('pageTwo') 2616 .onBackPressed(() => { 2617 this.pathStack.pop(new resultClass(0)); // 回退到上一个页面,将处理结果传入push的onPop回调。 2618 return true; 2619 }).onReady((context: NavDestinationContext) => { 2620 this.pathStack = context.pathStack 2621 }) 2622 } 2623} 2624``` 2625```json 2626// 工程配置文件module.json5中配置 {"routerMap": "$profile:route_map"} 2627// route_map.json 2628{ 2629 "routerMap": [ 2630 { 2631 "name": "pageOne", 2632 "pageSourceFile": "src/main/ets/pages/PageOne.ets", 2633 "buildFunction": "PageOneBuilder", 2634 "data": { 2635 "description": "this is pageOne" 2636 } 2637 }, 2638 { 2639 "name": "pageTwo", 2640 "pageSourceFile": "src/main/ets/pages/PageTwo.ets", 2641 "buildFunction": "PageTwoBuilder" 2642 } 2643 ] 2644} 2645``` 2646 2647 2648### 示例5 2649 2650该示例主要演示设置Navigation主页的标题栏、工具栏和NavDestination页面的标题栏的背景颜色和背景模糊效果。 2651 2652```ts 2653let COLOR1: string = "#80004AAF"; 2654let COLOR2: string = "#802787D9"; 2655let BLUR_STYLE_1: BlurStyle = BlurStyle.BACKGROUND_THIN; 2656let BLUR_STYLE_2: BlurStyle = BlurStyle.BACKGROUND_THICK; 2657 2658@Component 2659struct BackComponent { 2660 build() { 2661 Row() { 2662 Column() {} 2663 .height('100%') 2664 .backgroundColor("#3D9DB4") 2665 .layoutWeight(9) 2666 Column() {} 2667 .height('100%') 2668 .backgroundColor("17A98D") 2669 .layoutWeight(9) 2670 Column() {} 2671 .height('100%') 2672 .backgroundColor("FFC000") 2673 .layoutWeight(9) 2674 } 2675 .height('100%') 2676 .width('100%') 2677 } 2678} 2679 2680@Component 2681struct ColorAndBlur { 2682 @State useColor1: boolean = true; 2683 @State useBlur1: boolean = true; 2684 2685 build() { 2686 NavDestination() { 2687 Stack({alignContent: Alignment.Center}) { 2688 BackComponent() 2689 .width('100%') 2690 .height('100%') 2691 Column() { 2692 Stack({alignContent: Alignment.Center}) { 2693 Button("switch color") 2694 .onClick(() => { 2695 this.useColor1 = !this.useColor1; 2696 }) 2697 } 2698 .width('100%') 2699 .layoutWeight(1) 2700 Stack({alignContent: Alignment.Center}) { 2701 Button("switch blur") 2702 .onClick(() => { 2703 this.useBlur1 = !this.useBlur1; 2704 }) 2705 } 2706 .width('100%') 2707 .layoutWeight(1) 2708 } 2709 .width('100%') 2710 .height('100%') 2711 }.width('100%') 2712 .height('100%') 2713 } 2714 .width('100%') 2715 .height('100%') 2716 // 开发者可以设置标题栏的背景颜色和背景模糊效果 2717 .title("switch titlebar color and blur", { 2718 backgroundColor: this.useColor1 ? COLOR1 : COLOR2, 2719 backgroundBlurStyle: this.useBlur1 ? BLUR_STYLE_1 : BLUR_STYLE_2, 2720 barStyle: BarStyle.STACK 2721 }) 2722 } 2723} 2724 2725@Entry 2726@Component 2727struct Index { 2728 private stack: NavPathStack = new NavPathStack(); 2729 @State useColor1: boolean = true; 2730 @State useBlur1: boolean = true; 2731 2732 @Builder 2733 PageBuilder(name: string) { 2734 ColorAndBlur() 2735 } 2736 2737 build() { 2738 Navigation(this.stack) { 2739 Stack({alignContent: Alignment.Center}) { 2740 BackComponent() 2741 .width('100%') 2742 .height('100%') 2743 Column() { 2744 Stack({alignContent: Alignment.Center}) { 2745 Button("switch color") 2746 .onClick(() => { 2747 this.useColor1 = !this.useColor1; 2748 }) 2749 } 2750 .width('100%') 2751 .layoutWeight(1) 2752 Stack({alignContent: Alignment.Center}) { 2753 Button("switch blur") 2754 .onClick(() => { 2755 this.useBlur1 = !this.useBlur1; 2756 }) 2757 } 2758 .width('100%') 2759 .layoutWeight(1) 2760 Stack({alignContent: Alignment.Center}) { 2761 Button("push page") 2762 .onClick(() => { 2763 this.stack.pushPath({name: "page"}) 2764 }) 2765 } 2766 .width('100%') 2767 .layoutWeight(1) 2768 } 2769 .width('100%') 2770 .height('80%') 2771 }.width('100%') 2772 .height('100%') 2773 } 2774 .width('100%') 2775 .height('100%') 2776 .navDestination(this.PageBuilder) 2777 // 开发者可以设置标题栏的背景颜色和背景模糊效果 2778 .title("NavTitle", { 2779 backgroundColor: this.useColor1 ? COLOR1 : COLOR2, 2780 backgroundBlurStyle: this.useBlur1 ? BLUR_STYLE_1 : BLUR_STYLE_2, 2781 barStyle: BarStyle.STACK 2782 }) 2783 // 开发者可以设置工具栏的背景颜色和背景模糊效果 2784 .toolbarConfiguration([ 2785 {value: "a"}, 2786 {value: "b"}, 2787 {value: "c"} 2788 ], { 2789 backgroundColor: this.useColor1 ? COLOR1 : COLOR2, 2790 backgroundBlurStyle: this.useBlur1 ? BLUR_STYLE_1 : BLUR_STYLE_2 2791 }) 2792 } 2793} 2794``` 2795 2796 2797### 示例6 2798 2799该示例主要演示在嵌套Navigation场景下,如何获取父NavPathStack。 2800 2801```ts 2802@Entry 2803@Component 2804struct NavigationExample1 { 2805 @State childNavStack: NavPathStack = new NavPathStack(); 2806 2807 build() { 2808 Navigation() { 2809 Stack({alignContent: Alignment.Center}) { 2810 Navigation(this.childNavStack) { 2811 Button('push Path to parent Navigation', { stateEffect: true, type: ButtonType.Capsule }) 2812 .width('80%') 2813 .height(40) 2814 .margin(20) 2815 .onClick(() => { 2816 // 可以获取父NavPathStack 2817 let parentStack = this.childNavStack.getParent(); 2818 parentStack?.pushPath({ name: "pageOne"}) 2819 }) 2820 } 2821 .clip(true) 2822 .backgroundColor(Color.Orange) 2823 .width('80%') 2824 .height('80%') 2825 .title('ChildNavigation') 2826 } 2827 .width('100%') 2828 .height('100%') 2829 } 2830 .backgroundColor(Color.Green) 2831 .width('100%') 2832 .height('100%') 2833 .title('ParentNavigation') 2834 } 2835} 2836``` 2837```ts 2838// PageOne.ets 2839 @Builder 2840 export function PageOneBuilder(name: string) { 2841 NavDestination() { 2842 Text("this is " + name) 2843 } 2844 .title(name) 2845 } 2846``` 2847```json 2848// 工程配置文件module.json5中配置 {"routerMap": "$profile:route_map"} 2849// route_map.json 2850{ 2851 "routerMap": [ 2852 { 2853 "name": "pageOne", 2854 "pageSourceFile": "src/main/ets/pages/PageOne.ets", 2855 "buildFunction": "PageOneBuilder", 2856 "data": { 2857 "description": "this is pageOne" 2858 } 2859 } 2860 ] 2861} 2862``` 2863 2864 2865### 示例7 2866 2867该示例主要演示如下两点功能: 2868 28691. NavPathStack无需声明为状态变量,也可以实现页面栈操作功能。 2870 28712. NavDestination通过onReady事件能够拿到对应的NavPathInfo和所属的NavPathStack。 2872 2873```ts 2874class PageParam { 2875 constructor(num_: number) { 2876 this.num = num_; 2877 } 2878 num: number = 0; 2879} 2880 2881@Builder 2882export function PageOneBuilder(name: string, param: Object) { 2883 PageOne() 2884} 2885 2886@Component 2887struct PageOne { 2888 private stack: NavPathStack | null = null; 2889 private name: string = ""; 2890 private paramNum: number = 0; 2891 2892 build() { 2893 NavDestination() { 2894 Column() { 2895 Text("NavPathInfo: name: " + this.name + ", paramNum: " + this.paramNum) 2896 Button('pushPath', { stateEffect: true, type: ButtonType.Capsule }) 2897 .width('80%') 2898 .height(40) 2899 .margin(20) 2900 .onClick(() => { 2901 if (this.stack) { 2902 let p = new PageParam(this.paramNum + 1); 2903 this.stack.pushPath({name: "pageOne", param: p}); 2904 } 2905 }) 2906 Button('pop', { stateEffect: true, type: ButtonType.Capsule }) 2907 .width('80%') 2908 .height(40) 2909 .margin(20) 2910 .onClick(() => { 2911 this.stack?.pop() 2912 }) 2913 } 2914 .width('100%') 2915 .height('100%') 2916 } 2917 .title('pageOne') 2918 .onReady((ctx: NavDestinationContext) => { 2919 // 在NavDestination中能够拿到传来的NavPathInfo和当前所处的NavPathStack 2920 try { 2921 this.name = ctx?.pathInfo?.name; 2922 this.paramNum = (ctx?.pathInfo?.param as PageParam)?.num; 2923 this.stack = ctx.pathStack; 2924 } catch (e) { 2925 console.log(`testTag onReady catch exception: ${JSON.stringify(e)}`) 2926 } 2927 }) 2928 } 2929} 2930 2931@Entry 2932@Component 2933struct NavigationExample2 { 2934 private stack : NavPathStack = new NavPathStack(); 2935 2936 build() { 2937 Navigation(this.stack) { 2938 Stack({alignContent: Alignment.Center}) { 2939 Button('pushPath', { stateEffect: true, type: ButtonType.Capsule }) 2940 .width('80%') 2941 .height(40) 2942 .margin(20) 2943 .onClick(() => { 2944 let p = new PageParam(1); 2945 this.stack.pushPath({ name: "pageOne", param: p }) 2946 }) 2947 } 2948 .width('100%') 2949 .height('100%') 2950 } 2951 .width('100%') 2952 .height('100%') 2953 .title('Navigation') 2954 } 2955} 2956``` 2957```json 2958// 工程配置文件module.json5中配置 {"routerMap": "$profile:route_map"} 2959// route_map.json 2960{ 2961 "routerMap": [ 2962 { 2963 "name": "pageOne", 2964 "pageSourceFile": "src/main/ets/pages/Index.ets", 2965 "buildFunction": "PageOneBuilder", 2966 "data": { 2967 "description": "this is pageOne" 2968 } 2969 } 2970 ] 2971} 2972``` 2973 2974 2975### 示例8 2976 2977该示例演示NavDestination的生命周期时序。 2978 2979```ts 2980@Builder 2981export function PageOneBuilder(name: string, param: Object) { 2982 PageOneComponent() 2983} 2984 2985@Component 2986struct PageOneComponent { 2987 private stack: NavPathStack | null = null; 2988 @State eventStr: string = ""; 2989 2990 build() { 2991 NavDestination() { 2992 Column() { 2993 Text("event: " + this.eventStr) 2994 Button('pushPath', { stateEffect: true, type: ButtonType.Capsule }) 2995 .width('80%') 2996 .height(40) 2997 .margin(20) 2998 .onClick(() => { 2999 if (this.stack) { 3000 this.stack.pushPath({name: "pageOne"}); 3001 } 3002 }) 3003 Button('pop', { stateEffect: true, type: ButtonType.Capsule }) 3004 .width('80%') 3005 .height(40) 3006 .margin(20) 3007 .onClick(() => { 3008 this.stack?.pop() 3009 }) 3010 } 3011 .width('100%') 3012 .height('100%') 3013 } 3014 .title('pageOne') 3015 .onAppear(() => { this.eventStr += "<onAppear>"; }) 3016 .onDisAppear(() => { this.eventStr += "<onDisAppear>"; }) 3017 .onShown(() => { this.eventStr += "<onShown>"; }) 3018 .onHidden(() => { this.eventStr += "<onHidden>"; }) 3019 .onWillAppear(() => { this.eventStr += "<onWillAppear>"; }) 3020 .onWillDisappear(() => { this.eventStr += "<onWillDisappear>"; }) 3021 .onWillShow(() => { this.eventStr += "<onWillShow>"; }) 3022 .onWillHide(() => { this.eventStr += "<onWillHide>"; }) 3023 // onReady会在onAppear之前调用 3024 .onReady((ctx: NavDestinationContext) => { 3025 try { 3026 this.eventStr += "<onReady>"; 3027 this.stack = ctx.pathStack; 3028 } catch (e) { 3029 console.log(`testTag onReady catch exception: ${JSON.stringify(e)}`) 3030 } 3031 }) 3032 } 3033} 3034 3035@Entry 3036@Component 3037struct NavigationExample3 { 3038 private stack : NavPathStack = new NavPathStack(); 3039 3040 build() { 3041 Navigation(this.stack) { 3042 Stack({alignContent: Alignment.Center}) { 3043 Button('pushPath', { stateEffect: true, type: ButtonType.Capsule }) 3044 .width('80%') 3045 .height(40) 3046 .margin(20) 3047 .onClick(() => { 3048 this.stack.pushPath({ name: "pageOne" }) 3049 }) 3050 } 3051 .width('100%') 3052 .height('100%') 3053 } 3054 .width('100%') 3055 .height('100%') 3056 .title('Navigation') 3057 } 3058} 3059``` 3060```json 3061// 工程配置文件module.json5中配置 {"routerMap": "$profile:route_map"} 3062// route_map.json 3063{ 3064 "routerMap": [ 3065 { 3066 "name": "pageOne", 3067 "pageSourceFile": "src/main/ets/pages/Index.ets", 3068 "buildFunction": "PageOneBuilder", 3069 "data": { 3070 "description": "this is pageOne" 3071 } 3072 } 3073 ] 3074} 3075``` 3076 3077 3078 3079### 示例9 3080 3081该示例演示Navigation标题栏STACK布局效果。 3082 3083```ts 3084@Entry 3085@Component 3086struct NavigationExample { 3087 private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; 3088 private scrollerForScroll: Scroller = new Scroller(); 3089 @State barStyle: BarStyle = BarStyle.STANDARD; 3090 3091 build() { 3092 Column() { 3093 Navigation() { 3094 Column() { 3095 Scroll(this.scrollerForScroll) { 3096 Column() { 3097 Image($r('app.media.image_1')) 3098 // 设置与标题栏高度一致,以便观察STACK效果 3099 .height(138) 3100 .width('100%') 3101 Button('BarStyle.STANDARD') 3102 .height('50vp') 3103 .onClick(() => { 3104 this.barStyle = BarStyle.STANDARD; 3105 }) 3106 Button('BarStyle.STACK') 3107 .height('50vp') 3108 .margin({ top: 12 }) 3109 .onClick(() => { 3110 this.barStyle = BarStyle.STACK; 3111 }) 3112 3113 ForEach(this.arr, (item: number) => { 3114 ListItem() { 3115 Text('' + item) 3116 .width('100%') 3117 .height(100) 3118 .fontSize(16) 3119 .textAlign(TextAlign.Center) 3120 .borderRadius(10) 3121 .backgroundColor(Color.Orange) 3122 .margin({ top: 12 }) 3123 } 3124 }, (item: string) => item) 3125 } 3126 } 3127 } 3128 .width('100%') 3129 .height('100%') 3130 .backgroundColor(0xDCDCDC) 3131 } 3132 .title( 3133 { 3134 main: 'NavTitle', 3135 sub: 'subtitle' 3136 }, 3137 { 3138 backgroundBlurStyle: BlurStyle.COMPONENT_THICK, 3139 barStyle: this.barStyle, 3140 } 3141 ) 3142 .titleMode(NavigationTitleMode.Free) 3143 .hideTitleBar(false) 3144 }.width('100%').height('100%').backgroundColor('#F1F3F5') 3145 } 3146} 3147``` 3148 3149 3150 3151### 示例10 3152 3153该示例主要演示如何定义NavPathStack的派生类和派生类在Navigation中的基本用法。 3154 3155```ts 3156class DerivedNavPathStack extends NavPathStack { 3157 // usr defined property 'id' 3158 id: string = "__default__" 3159 3160 // new function in derived class 3161 setId(id: string) { 3162 this.id = id; 3163 } 3164 3165 // new function in derived class 3166 getInfo(): string { 3167 return "this page used Derived NavPathStack, id: " + this.id 3168 } 3169 3170 // overwrite function of NavPathStack 3171 pushPath(info: NavPathInfo, animated?: boolean): void 3172 pushPath(info: NavPathInfo, options?: NavigationOptions): void 3173 pushPath(info: NavPathInfo, secArg?: boolean | NavigationOptions): void { 3174 console.log('[derive-test] reached DerivedNavPathStack\'s pushPath'); 3175 if (typeof secArg === 'boolean') { 3176 super.pushPath(info, secArg); 3177 } else { 3178 super.pushPath(info, secArg); 3179 } 3180 } 3181 3182 // overwrite and overload function of NavPathStack 3183 pop(animated?: boolean | undefined): NavPathInfo | undefined 3184 pop(result: Object, animated?: boolean | undefined): NavPathInfo | undefined 3185 pop(result?: Object, animated?: boolean | undefined): NavPathInfo | undefined { 3186 console.log('[derive-test] reached DerivedNavPathStack\'s pop'); 3187 return super.pop(result, animated); 3188 } 3189 3190 // other function of base class... 3191} 3192 3193class param { 3194 info: string = "__default_param__"; 3195 constructor(info: string) { this.info = info } 3196} 3197 3198@Entry 3199@Component 3200struct Index { 3201 derivedStack: DerivedNavPathStack = new DerivedNavPathStack(); 3202 3203 aboutToAppear(): void { 3204 this.derivedStack.setId('origin stack'); 3205 } 3206 3207 @Builder 3208 pageMap(name: string) { 3209 PageOne() 3210 } 3211 3212 build() { 3213 Navigation(this.derivedStack) { 3214 Button('to Page One').margin(20).onClick(() => { 3215 this.derivedStack.pushPath({ 3216 name: 'pageOne', 3217 param: new param('push pageOne in homePage when stack size: ' + this.derivedStack.size()) 3218 }); 3219 }) 3220 }.navDestination(this.pageMap) 3221 .title('Home Page') 3222 } 3223} 3224 3225@Component 3226struct PageOne { 3227 derivedStack: DerivedNavPathStack = new DerivedNavPathStack(); 3228 curStringifyParam: string = "NA"; 3229 3230 build() { 3231 NavDestination() { 3232 Column() { 3233 Text(this.derivedStack.getInfo()) 3234 .margin(10) 3235 .fontSize(25) 3236 .fontWeight(FontWeight.Bold) 3237 .textAlign(TextAlign.Start) 3238 Text('current page param info:') 3239 .margin(10) 3240 .fontSize(25) 3241 .fontWeight(FontWeight.Bold) 3242 .textAlign(TextAlign.Start) 3243 Text(this.curStringifyParam) 3244 .margin(20) 3245 .fontSize(20) 3246 .textAlign(TextAlign.Start) 3247 }.backgroundColor(Color.Pink) 3248 Button('to Page One').margin(20).onClick(() => { 3249 this.derivedStack.pushPath({ 3250 name: 'pageOne', 3251 param: new param('push pageOne in pageOne when stack size: ' + this.derivedStack.size()) 3252 }); 3253 }) 3254 }.title('Page One') 3255 .onReady((context: NavDestinationContext) => { 3256 console.log('[derive-test] reached PageOne\'s onReady'); 3257 // get derived stack from navdestinationContext 3258 this.derivedStack = context.pathStack as DerivedNavPathStack; 3259 console.log('[derive-test] -- got derivedStack: ' + this.derivedStack.id); 3260 this.curStringifyParam = JSON.stringify(context.pathInfo.param); 3261 console.log('[derive-test] -- got param: ' + this.curStringifyParam); 3262 }) 3263 } 3264} 3265``` 3266 3267 3268### 示例11 3269 3270该示例主要演示Navigation和NavDestination如何使用Symbol组件。 3271 3272```ts 3273import { SymbolGlyphModifier } from '@kit.ArkUI'; 3274 3275@Entry 3276@Component 3277struct NavigationExample { 3278 @Provide('navPathStack') navPathStack:NavPathStack = new NavPathStack(); 3279 @State menuItems:Array<NavigationMenuItem> = [ 3280 { 3281 value:'menuItem1', 3282 icon:'resources/base/media/ic_public_ok.svg' // 图标资源路径 3283 }, 3284 { 3285 value:'menuItem2', 3286 icon:'resources/base/media/ic_public_ok.svg', // 图标资源路径 3287 symbolIcon: new SymbolGlyphModifier($r('sys.symbol.ohos_folder_badge_plus')).fontColor([Color.Red,Color.Green]).renderingStrategy(SymbolRenderingStrategy.MULTIPLE_COLOR), 3288 }, 3289 { 3290 value:'menuItem3', 3291 symbolIcon: new SymbolGlyphModifier($r('sys.symbol.ohos_lungs')), 3292 }, 3293 ] 3294 3295 @State toolItems:Array<ToolbarItem>= [ 3296 { 3297 value:'toolItem1', 3298 icon:'resources/base/media/ic_public_ok.svg', // 图标资源路径 3299 symbolIcon:new SymbolGlyphModifier($r('sys.symbol.ohos_lungs')), 3300 status:ToolbarItemStatus.ACTIVE, 3301 activeSymbolIcon: new SymbolGlyphModifier($r('sys.symbol.ohos_folder_badge_plus')).fontColor([Color.Red,Color.Green]).renderingStrategy(SymbolRenderingStrategy.MULTIPLE_COLOR), 3302 action:()=>{} 3303 }, 3304 { 3305 value:'toolItem2', 3306 symbolIcon:new SymbolGlyphModifier($r('sys.symbol.ohos_star')), 3307 status:ToolbarItemStatus.ACTIVE, 3308 activeIcon: 'resources/base/media/ic_public_more.svg', // 图标资源路径 3309 action:()=>{} 3310 }, 3311 { 3312 value:'toolItem3', 3313 symbolIcon:new SymbolGlyphModifier($r('sys.symbol.ohos_star')), 3314 status:ToolbarItemStatus.ACTIVE, 3315 activeSymbolIcon: new SymbolGlyphModifier($r('sys.symbol.ohos_lungs')), 3316 action:()=>{} 3317 } 3318 ] 3319 3320 @Builder 3321 myRouter(name:string,param?:Object) { 3322 if(name === 'NavigationMenu') { 3323 NavigationMenu(); 3324 } 3325 } 3326 3327 build() { 3328 Navigation(this.navPathStack) { 3329 Column() { 3330 Button('跳转').onClick(()=> { 3331 this.navPathStack.pushPathByName('NavigationMenu', null); 3332 }) 3333 } 3334 } 3335 .backButtonIcon(new SymbolGlyphModifier($r('sys.symbol.ohos_wifi'))) 3336 .titleMode(NavigationTitleMode.Mini) 3337 .menus(this.menuItems) 3338 .toolbarConfiguration(this.toolItems) 3339 .title('一级页面') 3340 .navDestination(this.myRouter) 3341 } 3342} 3343 3344@Component 3345export struct NavigationMenu{ 3346 @Consume('navPathStack') navPathStack:NavPathStack; 3347 @State menuItems:Array<NavigationMenuItem> = [ 3348 { 3349 value:'menuItem1', 3350 icon:'resources/base/media/ic_public_ok.svg', // 图标资源路径 3351 action:()=>{} 3352 }, 3353 { 3354 value:'menuItem2', 3355 symbolIcon: new SymbolGlyphModifier($r('sys.symbol.ohos_folder_badge_plus')).fontColor([Color.Red,Color.Green]).renderingStrategy(SymbolRenderingStrategy.MULTIPLE_COLOR), 3356 action:()=>{} 3357 }, 3358 { 3359 value:'menuItem3', 3360 symbolIcon: new SymbolGlyphModifier($r('sys.symbol.repeat_1')), 3361 action:()=>{} 3362 }, 3363 ] 3364 3365 build() { 3366 NavDestination(){ 3367 Row() { 3368 Column(){ 3369 } 3370 .width('100%') 3371 } 3372 .height('100%') 3373 } 3374 .hideTitleBar(false) 3375 .title('NavDestination title') 3376 .backgroundColor($r('sys.color.ohos_id_color_titlebar_sub_bg')) 3377 .backButtonIcon(new SymbolGlyphModifier($r('sys.symbol.ohos_star')).fontColor([Color.Blue])) 3378 .menus(this.menuItems) 3379 } 3380} 3381``` 3382 3383 3384### 示例12 3385 3386该示例主要演示Navigation和NavDestination如何设置自定义标题栏边距,如何通过TextModifier修改主副标题文本样式。 3387 3388```ts 3389import { LengthMetrics } from '@kit.ArkUI'; 3390import { TextModifier } from '@ohos.arkui.modifier'; 3391 3392class MainTitleTextModfier extends TextModifier { 3393 useStyle1: boolean = true; 3394 applyNormalAttribute(instance: TextModifier): void { 3395 if (this.useStyle1) { 3396 console.log(`testTag mainTitle use style1`); 3397 instance.fontColor('#FFFFC000') 3398 instance.fontSize(35) 3399 instance.fontWeight(FontWeight.Bolder) 3400 instance.fontStyle(FontStyle.Normal) 3401 instance.textShadow({radius: 5, offsetX: 9}) 3402 } else { 3403 console.log(`testTag mainTitle use style2`); 3404 instance.fontColor('#FF23A98D') 3405 instance.fontSize(20) 3406 instance.heightAdaptivePolicy(TextHeightAdaptivePolicy.MIN_FONT_SIZE_FIRST) 3407 instance.fontWeight(FontWeight.Lighter) 3408 instance.fontStyle(FontStyle.Italic) 3409 instance.textShadow({radius: 3, offsetX: 3}) 3410 } 3411 } 3412} 3413 3414class SubTitleTextModfier extends TextModifier { 3415 useStyle1: boolean = true; 3416 applyNormalAttribute(instance: TextModifier): void { 3417 if (this.useStyle1) { 3418 console.log(`testTag subTitle use style1`); 3419 instance.fontColor('#FFFFC000') 3420 instance.fontSize(15) 3421 instance.fontWeight(FontWeight.Bolder) 3422 instance.fontStyle(FontStyle.Normal) 3423 instance.textShadow({radius: 5, offsetX: 9}) 3424 } else { 3425 console.log(`testTag subTitle use style2`); 3426 instance.fontColor('#FF23A98D') 3427 instance.fontSize(10) 3428 instance.fontWeight(FontWeight.Lighter) 3429 instance.fontStyle(FontStyle.Italic) 3430 instance.textShadow({radius: 3, offsetX: 3}) 3431 } 3432 } 3433} 3434 3435@Entry 3436@Component 3437struct NavigationExample { 3438 private navPathStack: NavPathStack = new NavPathStack(); 3439 // 初始化标题栏起始端内间距 3440 @State paddingStart: LengthMetrics = LengthMetrics.vp(0); 3441 // 初始化标题栏结束端内间距 3442 @State paddingEnd: LengthMetrics = LengthMetrics.vp(0); 3443 // 主标题样式修改器 3444 @State mainTitleModifier: MainTitleTextModfier = new MainTitleTextModfier(); 3445 // 副标题样式修改器 3446 @State subTitleModifier: SubTitleTextModfier = new SubTitleTextModfier(); 3447 @State applyModifier: boolean = false; 3448 @State useStyle1: boolean = true; 3449 3450 @Builder 3451 myRouter(name: string, param?: Object) { 3452 if (name === 'NavDestinationExample') { 3453 NavDestinationExample(); 3454 } 3455 } 3456 3457 build() { 3458 Navigation(this.navPathStack) { 3459 Column() { 3460 // 标题栏内间距切换 3461 Button('apply padding 32vp') 3462 .onClick(() => { 3463 this.paddingStart = LengthMetrics.vp(32); 3464 this.paddingEnd = LengthMetrics.vp(32); 3465 }) 3466 .margin({top: 70}) 3467 .width(180) 3468 Button('apply padding 20vp') 3469 .onClick(() => { 3470 this.paddingStart = LengthMetrics.vp(20); 3471 this.paddingEnd = LengthMetrics.vp(20); 3472 }) 3473 .margin({top: 40}) 3474 .width(180) 3475 Button('pushPage') 3476 .onClick(() => { 3477 this.navPathStack.pushPath({name: 'NavDestinationExample'}) 3478 }) 3479 .margin({top: 40}) 3480 .width(180) 3481 Row() { 3482 Text(`apply Modifier`) 3483 Toggle({isOn: this.applyModifier, type: ToggleType.Switch}).onChange((isOn: boolean) => { 3484 this.applyModifier = isOn; 3485 }) 3486 } 3487 .padding({ top: 95, left: 5, right: 5 }) 3488 .width(180) 3489 .justifyContent(FlexAlign.SpaceBetween) 3490 Row() { 3491 Text(`use Style1`) 3492 Toggle({isOn: this.useStyle1, type: ToggleType.Switch}).onChange((isOn: boolean) => { 3493 this.mainTitleModifier.useStyle1 = isOn; 3494 this.subTitleModifier.useStyle1 = isOn; 3495 this.useStyle1 = isOn; 3496 }) 3497 } 3498 .padding({ top: 40, left: 5, right: 5 }) 3499 .width(180) 3500 .justifyContent(FlexAlign.SpaceBetween) 3501 } 3502 .width('100%') 3503 .height('100%') 3504 } 3505 .titleMode(NavigationTitleMode.Full) 3506 .title( 3507 {main: "Title", sub: "subTitle"}, 3508 this.applyModifier ? 3509 { 3510 paddingStart: this.paddingStart, 3511 paddingEnd: this.paddingEnd, 3512 mainTitleModifier: this.mainTitleModifier, 3513 subTitleModifier: this.subTitleModifier, 3514 } : { 3515 paddingStart: this.paddingStart, 3516 paddingEnd: this.paddingEnd 3517 }) 3518 .navDestination(this.myRouter) 3519 } 3520} 3521 3522@Component 3523export struct NavDestinationExample { 3524 @State menuItems: Array<NavigationMenuItem> = [ 3525 { 3526 value: 'menuItem1', 3527 icon: 'resources/base/media/ic_public_ok.svg', // 图标资源路径 3528 action: () => { 3529 } 3530 } 3531 ] 3532 @State paddingStart: LengthMetrics = LengthMetrics.vp(0); 3533 @State paddingEnd: LengthMetrics = LengthMetrics.vp(0); 3534 // 主标题样式修改器 3535 @State mainTitleModifier: MainTitleTextModfier = new MainTitleTextModfier(); 3536 // 副标题样式修改器 3537 @State subTitleModifier: SubTitleTextModfier = new SubTitleTextModfier(); 3538 @State applyModifier: boolean = false; 3539 @State useStyle1: boolean = true; 3540 3541 build() { 3542 NavDestination() { 3543 Column() { 3544 // 标题栏内间距切换 3545 Button('apply padding 32vp') 3546 .onClick(() => { 3547 this.paddingStart = LengthMetrics.vp(32); 3548 this.paddingEnd = LengthMetrics.vp(32); 3549 }) 3550 .margin({top: 150}) 3551 .width(180) 3552 Button('apply padding 20vp') 3553 .onClick(() => { 3554 this.paddingStart = LengthMetrics.vp(20); 3555 this.paddingEnd = LengthMetrics.vp(20); 3556 }) 3557 .margin({top: 40}) 3558 .width(180) 3559 Row() { 3560 Text(`apply Modifier`) 3561 Toggle({isOn: this.applyModifier, type: ToggleType.Switch}).onChange((isOn: boolean) => { 3562 this.applyModifier = isOn; 3563 }) 3564 } 3565 .padding({ top: 95, left: 5, right: 5 }) 3566 .width(180) 3567 .justifyContent(FlexAlign.SpaceBetween) 3568 Row() { 3569 Text(`use Style1`) 3570 Toggle({isOn: this.useStyle1, type: ToggleType.Switch}).onChange((isOn: boolean) => { 3571 this.mainTitleModifier.useStyle1 = isOn; 3572 this.subTitleModifier.useStyle1 = isOn; 3573 this.useStyle1 = isOn; 3574 }) 3575 } 3576 .padding({ top: 40, left: 5, right: 5 }) 3577 .width(180) 3578 .justifyContent(FlexAlign.SpaceBetween) 3579 } 3580 .width('100%') 3581 .height('90%') 3582 } 3583 .hideTitleBar(false) 3584 .title( 3585 {main: "Title", sub: "subTitle"}, 3586 this.applyModifier ? 3587 { 3588 paddingStart: this.paddingStart, 3589 paddingEnd: this.paddingEnd, 3590 mainTitleModifier: this.mainTitleModifier, 3591 subTitleModifier: this.subTitleModifier, 3592 } : { 3593 paddingStart: this.paddingStart, 3594 paddingEnd: this.paddingEnd 3595 }) 3596 .menus(this.menuItems) 3597 } 3598} 3599``` 3600 3601 3602### 示例13 3603 3604该示例主要实现Navigation简单的自定义转场动画。 3605```ts 3606// Index.ets 3607import { AnimateCallback, CustomTransition } from './CustomTransitionUtils' 3608 3609@Entry 3610@Component 3611struct NavigationCustomTransitionExample { 3612 pageInfos: NavPathStack = new NavPathStack(); 3613 3614 aboutToAppear() { 3615 this.pageInfos.pushPath({ name: 'PageOne' }, false); 3616 } 3617 3618 build() { 3619 Navigation(this.pageInfos) { 3620 } 3621 .hideNavBar(true) 3622 .customNavContentTransition((from: NavContentInfo, to: NavContentInfo, operation: NavigationOperation) => { 3623 // 首页不进行自定义动画 3624 if (from.index === -1 || to.index === -1) { 3625 return undefined; 3626 } 3627 3628 let customAnimation: NavigationAnimatedTransition = { 3629 timeout: 2000, 3630 // 转场开始时系统调用该方法,并传入转场上下文代理对象 3631 transition: (transitionProxy: NavigationTransitionProxy) => { 3632 if (!from.navDestinationId || !to.navDestinationId) { 3633 return; 3634 } 3635 // 从封装类CustomTransition中根据子页面的序列获取对应的转场动画回调 3636 let fromParam: AnimateCallback = CustomTransition.getInstance().getAnimateParam(from.navDestinationId); 3637 let toParam: AnimateCallback = CustomTransition.getInstance().getAnimateParam(to.navDestinationId); 3638 // Push动画 3639 if (operation == NavigationOperation.PUSH) { 3640 if (fromParam.start && toParam.start) { 3641 // 设置Push转场的两个页面的动画起点 3642 fromParam.start(true, true); 3643 toParam.start(true, false); 3644 } 3645 animateTo({ 3646 duration: 500, curve: Curve.Friction, onFinish: () => { 3647 // 动画结束后需要手动调用finishTransition,否则在timeout时间后由系统调用 3648 transitionProxy.finishTransition(); 3649 } 3650 }, () => { 3651 if (fromParam.finish && toParam.finish) { 3652 // 设置Push转场的两个页面的动画终点 3653 fromParam.finish(true, true); 3654 toParam.finish(true, false); 3655 } 3656 3657 }) 3658 } else if (operation == NavigationOperation.POP) { 3659 // Pop动画 3660 if (fromParam.start && toParam.start) { 3661 // 设置Pop转场的两个页面的动画起点 3662 fromParam.start(false, true); 3663 toParam.start(false, false); 3664 } 3665 animateTo({ 3666 duration: 500, curve: Curve.Friction, onFinish: () => { 3667 // 动画结束后需要手动调用finishTransition,否则在timeout时间后由系统调用 3668 transitionProxy.finishTransition(); 3669 } 3670 }, () => { 3671 if (fromParam.finish && toParam.finish) { 3672 // 设置Pop转场的两个页面的动画终点 3673 fromParam.finish(false, true); 3674 toParam.finish(false, false); 3675 } 3676 }) 3677 } else { 3678 // Replace不做动画 3679 } 3680 } 3681 }; 3682 return customAnimation; 3683 }) 3684 } 3685} 3686 3687 3688// PageOne 3689@Builder 3690export function PageOneBuilder() { 3691 PageContainer({ title: "PageOne" }) 3692} 3693 3694// PageTwo 3695@Builder 3696export function PageTwoBuilder() { 3697 PageContainer({ title: "PageTwo" }) 3698} 3699 3700@Component 3701export struct PageContainer { 3702 pageInfos: NavPathStack = new NavPathStack(); 3703 @State translateY: string = '0'; 3704 pageId: string = ''; 3705 title: string = '' 3706 3707 registerCallback() { 3708 CustomTransition.getInstance().registerNavParam(this.pageId, 3709 // 设置转场动画起点,根据不同的转场类型分别设置 3710 (isPush: boolean, isExit: boolean) => { 3711 if (isPush) { 3712 if (isExit) { 3713 this.translateY = '0'; 3714 } else { 3715 this.translateY = '100%'; 3716 } 3717 } else { 3718 if (isExit) { 3719 this.translateY = '0'; 3720 } else { 3721 this.translateY = '0'; 3722 } 3723 } 3724 }, 3725 // 设置转场动画终点,根据不同的转场类型分别设置 3726 (isPush: boolean, isExit: boolean) => { 3727 if (isPush) { 3728 if (isExit) { 3729 this.translateY = '0'; 3730 } else { 3731 this.translateY = '0'; 3732 } 3733 } else { 3734 if (isExit) { 3735 this.translateY = '100%'; 3736 } else { 3737 this.translateY = '0'; 3738 } 3739 } 3740 }); 3741 } 3742 3743 build() { 3744 NavDestination() { 3745 Column() { 3746 Button('push next page', { stateEffect: true, type: ButtonType.Capsule }) 3747 .width('80%') 3748 .height(40) 3749 .margin(20) 3750 .onClick(() => { 3751 this.pageInfos.pushPath({ name: this.title == 'PageOne' ? "PageTwo" : "PageOne" }) 3752 }) 3753 } 3754 .size({ width: '100%', height: '100%' }) 3755 } 3756 .title(this.title) 3757 .onDisAppear(() => { 3758 // 页面销毁时解注册自定义转场动画参数 3759 CustomTransition.getInstance().unRegisterNavParam(this.pageId); 3760 }) 3761 .onReady((context: NavDestinationContext) => { 3762 this.pageInfos = context.pathStack; 3763 if (context.navDestinationId) { 3764 this.pageId = context.navDestinationId; 3765 // 页面创建时注册自定义转场动画参数 3766 this.registerCallback(); 3767 } 3768 }) 3769 .translate({ y: this.translateY }) 3770 .backgroundColor(this.title == 'PageOne' ? '#F1F3F5' : '#ff11dee5') 3771 } 3772} 3773``` 3774```ts 3775// CustomNavigationUtils.ts 工具类,用来管理所有页面的自定义动画参数注册和获取等 3776 3777// 自定义接口,用来保存某个页面相关的转场动画回调和参数 3778export interface AnimateCallback { 3779 start: ((isPush: boolean, isExit: boolean) => void | undefined) | undefined; 3780 finish: ((isPush: boolean, isExit: boolean) => void | undefined) | undefined 3781} 3782 3783const customTransitionMap: Map<string, AnimateCallback> = new Map(); 3784 3785export class CustomTransition { 3786 static delegate = new CustomTransition(); 3787 3788 static getInstance() { 3789 return CustomTransition.delegate; 3790 } 3791 3792 /* 注册某个页面的动画回调 3793 * name: 注册页面的唯一id 3794 * startCallback:用来设置动画开始时页面的状态 3795 * endCallback:用来设置动画结束时页面的状态 3796 */ 3797 registerNavParam(name: string, startCallback: (isPush: boolean, isExit: boolean) => void, 3798 endCallback: (isPush: boolean, isExit: boolean) => void): void { 3799 if (customTransitionMap.has(name)) { 3800 let param = customTransitionMap.get(name); 3801 if (param != undefined) { 3802 param.start = startCallback; 3803 param.finish = endCallback; 3804 return; 3805 } 3806 } 3807 let params: AnimateCallback = { start: startCallback, finish: endCallback }; 3808 customTransitionMap.set(name, params); 3809 } 3810 3811 unRegisterNavParam(name: string): void { 3812 customTransitionMap.delete(name); 3813 } 3814 3815 getAnimateParam(name: string): AnimateCallback { 3816 let result: AnimateCallback = { 3817 start: customTransitionMap.get(name)?.start, 3818 finish: customTransitionMap.get(name)?.finish 3819 }; 3820 return result; 3821 } 3822} 3823``` 3824 3825```json 3826// 工程配置文件module.json5中配置 {"routerMap": "$profile:route_map"} 3827// route_map.json 3828{ 3829 "routerMap": [ 3830 { 3831 "name": "PageOne", 3832 "pageSourceFile": "src/main/ets/pages/Index.ets", 3833 "buildFunction": "PageOneBuilder", 3834 "data": { 3835 "description": "this is pageOne" 3836 } 3837 }, 3838 { 3839 "name": "PageTwo", 3840 "pageSourceFile": "src/main/ets/pages/Index.ets", 3841 "buildFunction": "PageTwoBuilder" 3842 } 3843 ] 3844} 3845``` 3846