1# MultiNavigation 2 3MultiNavigation用于在大尺寸设备上分栏显示、进行路由跳转。 4 5> **说明:** 6> 7> 该组件从API Version 14开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 8> 9> 由于MultiNavigation存在多重栈嵌套,调用本文档明确说明的不支持接口或不在本文档支持接口列表中的接口(例如getParent、setInterception、pushDestination等),可能会发生无法预期的问题。 10 11## 导入模块 12 13``` 14import { MultiNavigation, MultiNavPathStack, SplitPolicy } from '@kit.ArkUI'; 15``` 16 17## 子组件 18 19不可以包含子组件 20 21## MultiNavigation 22 23MultiNavigation(navDestination: navDestination, multiStack: MultiNavPathStack, onNavigationModeChange?: OnNavigationModeChangeCallback, onHomeShowOnTop?: OnHomeShowOnTopCallback) 24 25创建并初始化MultiNavigation组件。 26 27MultiNavigation组件遵循默认的左起右清栈规则,这意味着从左侧主页点击时,会触发详情页的加载并同时清除右侧所有其他详情页,确保右侧仅展示最新加载的详情页。然而,若在右侧的详情页上再次执行详情页加载操作,系统将不会执行清栈动作。 28 29**装饰器类型:**@Component 30 31**原子化服务API:** 从API version 14开始,该接口支持在原子化服务中使用。 32 33**系统能力:** SystemCapability.ArkUI.ArkUI.Full 34 35**参数:** 36 37| 名称 | 类型 | 必填 | 装饰器类型 | 说明 | 38|:---------:|:----------------------:|-----| ------ |-----------| 39| multiStack | [MultiNavPathStack](#multinavpathstack) | 是 | @State | 设置路由栈。 | 40| navDestination | [NavDestinationBuildFunction](#navdestinationbuildfunction) | 是 | @BuilderParam | 设置加载目标页面的路由规则。 | 41| onNavigationModeChange | [OnNavigationModeChangeCallback](#onnavigationmodechangecallback) | 否 | - | 设置MultiNavigation模式变更时的回调。 | 42| onHomeShowOnTop | [OnHomeShowOnTopCallback](#onhomeshowontopcallback) | 否 | - | 设置主页处于栈顶时的回调。 | 43 44## MultiNavPathStack 45 46当前,MultiNavigation的路由栈仅支持由使用方自行创建,不支持通过回调方式获取。请勿使用NavDestination的onReady等类似事件或接口来获取NavPathStack并进行栈操作,因为这可能会导致不可预知的问题。 47 48**原子化服务API:** 从API version 14开始,该接口支持在原子化服务中使用。 49 50**系统能力:** SystemCapability.ArkUI.ArkUI.Full 51 52### pushPath 53 54pushPath(info: NavPathInfo, animated?: boolean, policy?: SplitPolicy): void 55 56将指定的NavDestination页面信息入栈。 57 58**参数:** 59 60| 名称 | 类型 | 必填 | 描述 | 61| :------: | :----------------------------------------------------------: | :--: | ----------------------------------------- | 62| info | [NavPathInfo](./ts-basic-components-navigation.md#navpathinfo10) | 是 | NavDestination页面的信息。 | 63| animated | boolean | 否 | 是否支持转场动画,默认值:true。 | 64| policy | [SplitPolicy](#splitpolicy枚举说明) | 否 | 当前入栈页面的策略,默认值:DETAIL_PAGE。 | 65 66### pushPath 67 68pushPath(info: NavPathInfo, options?: NavigationOptions, policy?: SplitPolicy): void 69 70将指定的NavDestination页面信息入栈,通过NavigationOptions设置页面栈操作选项。 71 72**参数:** 73 74| 名称 | 类型 | 必填 | 描述 | 75| :-----: | :----------------------------------------------------------: | :--: | ------------------------------------------ | 76| info | [NavPathInfo](./ts-basic-components-navigation.md#navpathinfo10) | 是 | NavDestination页面的信息。 | 77| options | [NavigationOptions](./ts-basic-components-navigation.md#navigationoptions12) | 否 | 页面栈操作选项。仅支持其中的animated字段。 | 78| policy | [SplitPolicy](#splitpolicy枚举说明) | 否 | 当前入栈页面的策略,默认值:DETAIL_PAGE | 79 80### pushPathByName 81 82pushPathByName(name: string, param: Object, animated?: boolean, policy?: SplitPolicy): void 83 84将name指定的NavDestination页面信息入栈,传递的数据为param。 85 86**参数:** 87 88| 名称 | 类型 | 必填 | 描述 | 89|:---------------------:|:------------:|:------:| --------------------- | 90| name | string | 是 | NavDestination页面名称。 | 91| param | Object | 是 | NavDestination页面详细参数。 | 92| animated | boolean | 否 | 是否支持转场动画,默认值:true。 | 93| policy | [SplitPolicy](#splitpolicy枚举说明) | 否 | 当前入栈页面的策略,默认值:DETAIL_PAGE | 94 95### pushPathByName 96 97pushPathByName(name: string, param: Object, onPop: Callback\<PopInfo>, animated?: boolean, policy?: SplitPolicy): void 98 99将name指定的NavDestination页面信息入栈,传递的数据为param,添加onPop回调接收入栈页面出栈时的返回结果,并进行处理。 100 101**参数:** 102 103| 名称 | 类型 | 必填 | 描述 | 104|:---------:|:-------------------------------------------------------------:|:------:|------| 105| name | string | 是 | NavDestination页面名称。 | 106| param | Object | 是 | NavDestination页面详细参数。 | 107| onPop | Callback\<[PopInfo](ts-basic-components-navigation.md#popinfo11)> | 是 | Callback回调,用于页面出栈时触发该回调处理返回结果。 | 108| animated | boolean | 否 | 是否支持转场动画,默认值:true。 | 109| policy | [SplitPolicy](#splitpolicy枚举说明) | 否 | 当前入栈页面的策略,默认值:DETAIL_PAGE | 110 111### replacePath 112 113replacePath(info: NavPathInfo, animated?: boolean): void 114 115将当前页面栈栈顶退出,将指定的NavDestination页面信息入栈,新页面的分栏策略继承原栈顶页面的策略。 116 117**参数:** 118 119| 名称 | 类型 | 必填 | 描述 | 120| :------: | :----------------------------------------------------------: | :--: | -------------------------------- | 121| info | [NavPathInfo](./ts-basic-components-navigation.md#navpathinfo10) | 是 | NavDestination页面的信息。 | 122| animated | boolean | 否 | 是否支持转场动画,默认值:true。 | 123 124### replacePath 125 126replacePath(info: NavPathInfo, options?: NavigationOptions): void 127 128将当前页面栈栈顶退出,将指定的NavDestination页面信息入栈,新页面的分栏策略继承原栈顶页面的策略,通过NavigationOptions设置页面栈操作选项。 129 130**参数:** 131 132| 名称 | 类型 | 必填 | 描述 | 133| :-----: | :----------------------------------------------------------: | :--: | ------------------------------------------ | 134| info | [NavPathInfo](./ts-basic-components-navigation.md#navpathinfo10) | 是 | NavDestination页面的信息。 | 135| options | [NavigationOptions](./ts-basic-components-navigation.md#navigationoptions12) | 否 | 页面栈操作选项。仅支持其中的animated字段。 | 136 137### replacePathByName 138 139replacePathByName(name: string, param: Object, animated?: boolean): void 140 141将当前页面栈栈顶退出,将name指定的页面入栈,新页面的分栏策略继承原栈顶页面的策略。 142 143**参数:** 144 145| 名称 | 类型 | 必填 | 描述 | 146|:--------:|:---------:|:------:|----------------------| 147| name | string | 是 | NavDestination页面名称。 | 148| param | Object | 是 | NavDestination页面详细参数。 | 149| animated | boolean | 否 | 是否支持转场动画,默认值:true。 | 150 151### removeByIndexes 152 153removeByIndexes(indexes: Array<number\>): number 154 155将页面栈内索引值在indexes中的NavDestination页面删除。 156 157**参数:** 158 159| 名称 | 类型 | 必填 | 描述 | 160|:--------:|:---------------:|:------:| --------------------- | 161| indexes | Array<number\> | 是 | 待删除NavDestination页面的索引值数组。 | 162 163**返回值:** 164 165| 类型 | 说明 | 166|:-------------:| ------------------------ | 167| number | 返回删除的NavDestination页面数量。 | 168 169### removeByName 170 171removeByName(name: string): number 172 173将页面栈内指定name的NavDestination页面删除。 174 175**参数:** 176 177| 名称 | 类型 | 必填 | 描述 | 178|:-------:| ------- | ---- | --------------------- | 179| name | string | 是 | 待删除NavDestination页面的名字。 | 180 181**返回值:** 182 183| 类型 | 说明 | 184|:-------------:| ------------------------ | 185| number | 返回删除的NavDestination页面数量。 | 186 187### pop 188 189pop(animated?: boolean): NavPathInfo | undefined 190 191弹出路由栈栈顶元素。 192 193> **说明:** 194> 195> 当调用[keepBottomPage](#keepbottompage)接口并设置为true时,会保留栈底页面。 196 197**参数:** 198 199| 名称 | 类型 | 必填 | 描述 | 200|:-----------:|:--------:|:------:| -------------------- | 201| animated | boolean | 否 | 是否支持转场动画,默认值:true。 | 202 203**返回值:** 204 205| 类型 | 说明 | 206| ----------- | ------------------------ | 207| [NavPathInfo](./ts-basic-components-navigation.md#navpathinfo10) \| undefined | 返回栈顶NavDestination页面的信息。 | 208 209### pop 210 211pop(result: Object, animated?: boolean): NavPathInfo | undefined 212 213弹出路由栈栈顶元素,并触发onPop回调传入页面处理结果。 214 215> **说明:** 216> 217> 当调用[keepBottomPage](#keepbottompage)接口并设置为true时,会保留栈底页面。 218 219**参数:** 220 221| 名称 | 类型 | 必填 | 描述 | 222|:---------:|:-------------------------------:|:------:| -------------------- | 223| result | Object | 是 | 页面自定义处理结果。 | 224| animated | boolean | 否 | 是否支持转场动画,默认值:true。 | 225 226**返回值:** 227 228| 类型 | 说明 | 229| ----------- | ------------------------ | 230| [NavPathInfo](./ts-basic-components-navigation.md#navpathinfo10) \| undefined | 返回栈顶NavDestination页面的信息。 | 231 232### popToName 233 234popToName(name: string, animated?: boolean): number 235 236回退路由栈到由栈底开始第一个名为name的NavDestination页面。 237 238**参数:** 239 240| 名称 | 类型 | 必填 | 描述 | 241|:----------:|:--------:|:------:| ------------------- | 242| name | string | 是 | NavDestination页面名称。 | 243| animated | boolean | 否 | 是否支持转场动画,默认值:true。 | 244 245**返回值:** 246 247| 类型 | 说明 | 248| ------ | ---------------------------------------- | 249| number | 如果栈中存在名为name的NavDestination页面,则返回由栈底开始第一个名为name的NavDestination页面的索引,否则返回-1。 | 250 251### popToName 252 253popToName(name: string, result: Object, animated?: boolean): number 254 255回退路由栈到由栈底开始第一个名为name的NavDestination页面,并触发onPop回调传入页面处理结果。 256 257**参数:** 258 259| 名称 | 类型 | 必填 | 描述 | 260|:---------:|:--------:|:------:| ------------------- | 261| name | string | 是 | NavDestination页面名称。 | 262| result | Object | 是 | 页面自定义处理结果。 | 263| animated | boolean | 否 | 是否支持转场动画,默认值:true。 | 264 265**返回值:** 266 267| 类型 | 说明 | 268| ------ | ---------------------------------------- | 269| number | 如果栈中存在名为name的NavDestination页面,则返回由栈底开始第一个名为name的NavDestination页面的索引,否则返回-1。 | 270 271### popToIndex 272 273popToIndex(index: number, animated?: boolean): void 274 275回退路由栈到index指定的NavDestination页面。 276 277**参数:** 278 279| 名称 | 类型 | 必填 | 描述 | 280|:------------:|:--------:|:------:| ---------------------- | 281| index | number | 是 | NavDestination页面的位置索引。 | 282| animated | boolean | 否 | 是否支持转场动画,默认值:true。 | 283 284### popToIndex 285 286popToIndex(index: number, result: Object, animated?: boolean): void 287 288回退路由栈到index指定的NavDestination页面,并触发onPop回调传入页面处理结果。 289 290**参数:** 291 292| 名称 | 类型 | 必填 | 描述 | 293| ----- | ------ | ---- | ---------------------- | 294| index | number | 是 | NavDestination页面的位置索引。 | 295| result | Object | 是 | 页面自定义处理结果。 | 296| animated | boolean | 否 | 是否支持转场动画,默认值:true。 | 297 298### moveToTop 299 300moveToTop(name: string, animated?: boolean): number 301 302将由栈底开始第一个名为name的NavDestination页面移到栈顶。 303 304> **说明:** 305> 306> 根据找到的第一个名为name的页面的不同,MultiNavigation会进行不同的处理: 307> 308> 1)当找到的是最上层主页或者全屏页,此时不做任何处理; 309> 310> 2)当找到的是最上层主页对应的详情页,则会将对应的的详情页移到栈顶; 311> 312> 3)当找到的是非最上层的主页,则会将主页和对应所有详情页移到栈顶,详情页相对栈关系不变; 313> 314> 4)当找到的是非最上层的详情页,则会将主页和对应所有详情页移到栈顶,且将目标详情页移动到对应所有详情页的栈顶; 315> 316> 5)当找到的是非最上层的全屏页,则会将全屏页移动到栈顶。 317 318| 名称 | 类型 | 必填 | 描述 | 319|:---------:|:--------:|:------:| ------------------- | 320| name | string | 是 | NavDestination页面名称。 | 321| animated | boolean | 否 | 是否支持转场动画,默认值:true。 | 322 323**返回值:** 324 325| 类型 | 说明 | 326|:--------:|:----------------------------------------------------------------------------:| 327| number | 如果栈中存在名为name的NavDestination页面,则返回由栈底开始第一个名为name的NavDestination页面的索引,否则返回-1。 | 328 329### moveIndexToTop 330 331moveIndexToTop(index: number, animated?: boolean): void 332 333将指定index的NavDestination页面移到栈顶。 334 335> **说明:** 336> 337> 根据找到的第一个名为name的页面的不同,MultiNavigation会进行不同的处理: 338> 339> 1)当找到的是最上层主页或者全屏页,此时不做任何处理; 340> 341> 2)当找到的是最上层主页对应的详情页,则会将对应的的详情页移到栈顶; 342> 343> 3)当找到的是非最上层的主页,则会将主页和对应所有详情页移到栈顶,详情页相对栈关系不变; 344> 345> 4)当找到的是非最上层的详情页,则会将主页和对应所有详情页移到栈顶,且将目标详情页移动到对应所有详情页的栈顶; 346> 347> 5)当找到的是非最上层的全屏页,则会将全屏页移动到栈顶。 348 349| 名称 | 类型 | 必填 | 描述 | 350|:---------:|:-------:|:------:| ------------------- | 351| index | number | 是 | NavDestination页面的位置索引。 | 352| animated | boolean | 否 | 是否支持转场动画,默认值:true。 | 353 354### clear 355 356clear(animated?: boolean): void 357 358清除栈中所有页面。 359 360> **说明:** 361> 362> 当调用[keepBottomPage](#keepbottompage)接口并设置为true时,会保留栈底页面。 363 364**参数:** 365 366| 名称 | 类型 | 必填 | 描述 | 367|:---------:|:--------:|:------:| ---------------------- | 368| animated | boolean | 否 | 是否支持转场动画,默认值:true。 | 369 370### getAllPathName 371 372getAllPathName(): Array<string\> 373 374获取栈中所有NavDestination页面的名称。 375 376**返回值:** 377 378| 类型 | 说明 | 379|:----------------:| -------------------------- | 380| Array<string\> | 返回栈中所有NavDestination页面的名称。 | 381 382### getParamByIndex 383 384getParamByIndex(index: number): Object | undefined 385 386获取index指定的NavDestination页面的参数信息。 387 388**参数:** 389 390| 名称 | 类型 | 必填 | 描述 | 391|:-------:|:--------:|:------:| ---------------------- | 392| index | number | 是 | NavDestination页面的位置索引。 | 393 394**返回值:** 395 396| 类型 | 说明 | 397| --------- | -------------------------- | 398| Object | 返回对应NavDestination页面的参数信息。 | 399| undefined | 传入index无效是返回undefined。| 400 401### getParamByName 402 403getParamByName(name: string): Array<Object\> 404 405获取全部名为name的NavDestination页面的参数信息。 406 407**参数:** 408 409| 名称 | 类型 | 必填 | 描述 | 410|:------:|:--------:|:------:| ------------------- | 411| name | string | 是 | NavDestination页面名称。 | 412 413**返回值:** 414 415| 类型 | 说明 | 416| --------------- | --------------------------------- | 417| Array<Object\> | 返回全部名为name的NavDestination页面的参数信息。 | 418 419### getIndexByName 420 421getIndexByName(name: string): Array<number\> 422 423获取全部名为name的NavDestination页面的位置索引。 424 425**参数:** 426 427| 名称 | 类型 | 必填 | 描述 | 428|:------:|:--------:|:------:| ------------------- | 429| name | string | 是 | NavDestination页面名称。 | 430 431**返回值:** 432 433| 类型 | 说明 | 434| -------------- | --------------------------------- | 435| Array<number\> | 返回全部名为name的NavDestination页面的位置索引。 | 436 437### size 438 439size(): number 440 441获取栈大小。 442 443**返回值:** 444 445| 类型 | 说明 | 446| ------ | ------ | 447| number | 返回栈大小。 | 448 449### disableAnimation 450 451disableAnimation(value: boolean): void 452 453关闭(true)或打开(false)当前MultiNavigation中所有转场动画。 454 455**参数:** 456 457| 名称 | 类型 | 必填 | 描述 | 458| ----- | ------ | ---- | ---------------------- | 459| value | boolean | 否 | 是否关闭转场动画,默认值:false。 | 460 461### switchFullScreenState 462 463switchFullScreenState(isFullScreen?: boolean): boolean 464 465切换当前顶栈详情页面的显示模式。设置为true表示为全屏显示,false表示分栏显示。 466 467**参数:** 468 469| 名称 | 类型 | 必填 | 描述 | 470| :----------: | :-----: | :--: | ----------------------------------------------------- | 471| isFullScreen | boolean | 是 | 是否切换为全屏。true表示全屏模式,false表示分栏模式。 | 472 473**返回值:** 474 475| 类型 | 说明 | 476|:--------:|:----------:| 477| boolean | 切换成功或失败。 | 478 479### setHomeWidthRange 480 481setHomeWidthRange(minPercent: number, maxPercent: number): void 482 483设置主页宽度可拖动范围。应用不设置的情况下宽度为50%,且不可拖动。 484 485**参数:** 486 487| 名称 | 类型 | 必填 | 描述 | 488|:-------------:|:--------:|:-----:|-------------------| 489| minPercent | number | 是 | 最小主页宽度百分比。 | 490| maxPercent | number | 是 | 最大主页宽度百分比。 | 491 492### keepBottomPage 493 494keepBottomPage(keepBottom: boolean): void 495 496设置在调用pop和clear接口时是否保留栈底页面, 497 498> **说明:** 499> 500> MultiNavigation将主页也当作了NavDestination页面入栈,所以调用pop或clear接口时会将栈底页面也出栈。 501> 应用调用此接口并设置为TRUE时,MultiNavigation会在调用pop和clear接口时保留栈底页面。 502 503**参数:** 504 505| 名称 | 类型 | 必填 | 描述 | 506|:-------------:|:--------:|:-----:|--------------------| 507| keepBottom | boolean | 是 | 是否保留栈底页面,默认为FALSE。 | 508 509### setPlaceholderPage 510 511setPlaceholderPage(info: NavPathInfo): void 512 513设置占位页面。 514 515> **说明** 516> 517> 占位页面为特殊页面类型,当应用设置后,在一些大屏设备上会和主页默认形成左右分栏的效果,即左边主页,右边占位页。 518> 519> 当应用可绘制区域小于600VP、折叠屏由展开态切换为折叠态及平板横屏转竖屏等场景时,会自动将占位页出栈,只显示主页; 520> 而当应用可绘制区域大于等于600VP、折叠屏由折叠态切换为展开态及平板竖屏转横屏等场景时,会自动补充占位页,形成分栏。 521 522**参数:** 523 524| 名称 | 类型 | 必填 | 描述 | 525|:-------------:|:--------:|:-----:|----------| 526| info | NavPathInfo | 是 | 占位页页面信息。 | 527 528## SplitPolicy枚举说明 529 530表示MultiNavigation中页面的类型。 531 532**原子化服务API:** 从API version 14开始,该接口支持在原子化服务中使用。 533 534**系统能力:** SystemCapability.ArkUI.ArkUI.Full 535 536| 名称 | 值 | 说明 | 537| :---------------: | :-: | :-------------: | 538| HOME_PAGE | 0 | 主页页面类型。全屏模式显示 | 539| DETAIL_PAGE | 1 | 详情页页面类型。分栏模式显示 | 540| FULL_PAGE | 2 | 全屏页页面类型。全屏模式显示 | 541 542## NavDestinationBuildFunction 543 544type NavDestinationBuildFunction = (name: string, param?: object) => void 545 546MultiNavigation用以加载NavDestination的方法。 547 548**原子化服务API:** 从API version 14开始,该接口支持在原子化服务中使用。 549 550**系统能力:** SystemCapability.ArkUI.ArkUI.Full 551 552| 名称 | 类型 | 必填 | 说明 | 553| --------------- | ------ |------ |------ | 554|name | string |是| 路由页面的标识符。 | 555| param | object | 否 | 路由跳转创建页面时传递的参数。 | 556 557## OnNavigationModeChangeCallback 558 559type OnNavigationModeChangeCallback = (mode: NavigationMode) => void 560 561当MultiNavigation的mode变化时触发的回调函数。 562 563**原子化服务API:** 从API version 14开始,该接口支持在原子化服务中使用。 564 565**系统能力:** SystemCapability.ArkUI.ArkUI.Full 566 567| 名称 | 类型 | 必填 | 说明 | 568| ---- | ------------------------------------------------------------ | ---- | ------------------------------ | 569| mode | [NavigationMode](./ts-basic-components-navigation.md#navigationmode9) | 是 | 当回调触发时的NavigationMode。 | 570 571## OnHomeShowOnTopCallback 572 573type OnHomeShowOnTopCallback = (name: string) => void 574 575当主页在栈顶显示时触发的回调函数。 576 577**原子化服务API:** 从API version 14开始,该接口支持在原子化服务中使用。 578 579**系统能力:** SystemCapability.ArkUI.ArkUI.Full 580 581| 名称 | 类型 | 必填 | 说明 | 582| ---- | ------ | ---- | -------------------------- | 583| name | string | 是 | 显示在栈顶的页面的标识符。 | 584 585## 属性 586 587不支持[通用属性](ts-universal-attributes-size.md) 588 589## 事件 590 591不支持[通用事件](ts-universal-events-click.md) 592 593## 示例 594 595本示例演示MultiNavigation的基本功能 596 597```typescript 598// pages/Index.ets 599import { MultiNavigation, MultiNavPathStack, SplitPolicy } from '@ohos.arkui.advanced.MultiNavigation'; 600import { PageDetail1 } from './PageDetail1'; 601import { PageDetail2 } from './PageDetail2'; 602import { PageFull1 } from './PageFull1'; 603import { PageHome1 } from './PageHome1'; 604import { PagePlaceholder } from './PagePlaceholder'; 605 606@Entry 607@Component 608struct Index { 609 @Provide('pageStack') pageStack: MultiNavPathStack = new MultiNavPathStack(); 610 611 @Builder 612 PageMap(name: string, param?: object) { 613 if (name === 'PageHome1') { 614 PageHome1({ param: param }) 615 } else if (name === 'PageDetail1') { 616 PageDetail1({ param: param }); 617 } else if (name === 'PageDetail2') { 618 PageDetail2({ param: param }); 619 } else if (name === 'PageFull1') { 620 PageFull1(); 621 } else if (name === 'PagePlaceholder') { 622 PagePlaceholder(); 623 } 624 } 625 626 aboutToAppear(): void { 627 this.pageStack.pushPathByName('PageHome1', 'paramTest', false, SplitPolicy.HOME_PAGE); 628 } 629 630 build() { 631 Column() { 632 Row() { 633 MultiNavigation({ navDestination: this.PageMap, multiStack: this.pageStack }) 634 } 635 .width('100%') 636 } 637 } 638} 639``` 640 641```typescript 642// pages/PageHome1.ets, 对应首页 643import { MultiNavPathStack, SplitPolicy } from '@ohos.arkui.advanced.MultiNavigation'; 644import { hilog } from '@kit.PerformanceAnalysisKit'; 645 646@Component 647export struct PageHome1 { 648 @State message: string = 'PageHome1'; 649 @Consume('pageStack') pageStack: MultiNavPathStack; 650 controller: TextInputController = new TextInputController() 651 text: String = ''; 652 index: number = 0; 653 param: Object = new Object(); 654 lastBackTime: number = 0; 655 656 build() { 657 if (this.log()) { 658 NavDestination() { 659 Column() { 660 Column() { 661 Text(this.message) 662 .fontSize(40) 663 .fontWeight(FontWeight.Bold) 664 } 665 .width('100%') 666 .height('8%') 667 Scroll(){ 668 Column() { 669 Button('OpenHome', { stateEffect: true, type: ButtonType.Capsule}) 670 .width('50%') 671 .height(40) 672 .margin(20) 673 .onClick(() => { 674 if (this.pageStack !== undefined && this.pageStack !== null) { 675 this.pageStack.pushPathByName('PageHome1', 'testParam', true, SplitPolicy.HOME_PAGE); 676 this.index++; 677 } 678 }) 679 Button('OpenDetail', { stateEffect: true, type: ButtonType.Capsule}) 680 .width('50%') 681 .height(40) 682 .margin(20) 683 .onClick(() => { 684 if (this.pageStack !== undefined && this.pageStack !== null) { 685 this.pageStack.pushPathByName('PageDetail1', 'testParam'); 686 this.index++; 687 } 688 }) 689 Button('OpenFull', { stateEffect: true, type: ButtonType.Capsule}) 690 .width('50%') 691 .height(40) 692 .margin(20) 693 .onClick(() => { 694 if (this.pageStack !== undefined && this.pageStack !== null) { 695 this.pageStack.pushPathByName('PageFull1', 'testParam', true, SplitPolicy.FULL_PAGE); 696 } 697 }) 698 TextInput({placeholder: 'input your poptoindex ...', controller: this.controller }) 699 .placeholderColor(Color.Grey) 700 .placeholderFont({ size: 14, weight: 400 }) 701 .caretColor(Color.Blue) 702 .width('50%') 703 .height(40) 704 .margin(20) 705 .type(InputType.Number) 706 .fontSize(14) 707 .fontColor(Color.Black) 708 .onChange((value: String) => { 709 this.text = value 710 }) 711 Button('poptoindex', { stateEffect: true, type: ButtonType.Capsule}) 712 .width('50%') 713 .height(40) 714 .margin(20) 715 .onClick(() => { 716 if (this.pageStack !== undefined && this.pageStack !== null) { 717 this.pageStack.popToIndex(Number(this.text)); 718 this.controller.caretPosition(1) 719 } 720 }) 721 Button('OpenDetailWithName', { stateEffect: true, type: ButtonType.Capsule}) 722 .width('50%') 723 .height(40) 724 .margin(20) 725 .onClick(() => { 726 if (this.pageStack !== undefined && this.pageStack !== null) { 727 this.pageStack.pushPathByName('PageDetail1', 'testParam', undefined, true); 728 } 729 }) 730 Button('pop', { stateEffect: true, type: ButtonType.Capsule}) 731 .width('50%') 732 .height(40) 733 .margin(20) 734 .onClick(() => { 735 if (this.pageStack !== undefined && this.pageStack !== null) { 736 this.pageStack.pop(); 737 } 738 }) 739 Button('moveToTopByName: PageDetail1', { stateEffect: true, type: ButtonType.Capsule}) 740 .width('50%') 741 .height(40) 742 .margin(10) 743 .onClick(() => { 744 if (this.pageStack !== undefined && this.pageStack !== null) { 745 let indexFound = this.pageStack.moveToTop('PageDetail1'); 746 hilog.info(0x0000, 'demoTest', 'moveToTopByName,indexFound:' + indexFound); 747 } 748 }) 749 Button('removeByName HOME', { stateEffect: true, type: ButtonType.Capsule}) 750 .width('50%') 751 .height(40) 752 .margin(20) 753 .onClick(() => { 754 if (this.pageStack !== undefined && this.pageStack !== null) { 755 this.pageStack.removeByName('PageHome1'); 756 } 757 }) 758 Button('removeByIndexes 0135', { stateEffect: true, type: ButtonType.Capsule}) 759 .width('50%') 760 .height(40) 761 .margin(20) 762 .onClick(() => { 763 if (this.pageStack !== undefined && this.pageStack !== null) { 764 this.pageStack.removeByIndexes([0,1,3,5]); 765 } 766 }) 767 Button('getAllPathName', { stateEffect: true, type: ButtonType.Capsule}) 768 .width('50%') 769 .height(40) 770 .margin(20) 771 .onClick(() => { 772 if (this.pageStack !== undefined && this.pageStack !== null) { 773 let result = this.pageStack.getAllPathName(); 774 hilog.info(0x0000, 'demotest', 'getAllPathName: ' + result.toString()); 775 } 776 }) 777 Button('getParamByIndex0', { stateEffect: true, type: ButtonType.Capsule}) 778 .width('50%') 779 .height(40) 780 .margin(20) 781 .onClick(() => { 782 if (this.pageStack !== undefined && this.pageStack !== null) { 783 let result = this.pageStack.getParamByIndex(0); 784 hilog.info(0x0000, 'demotest', 'getParamByIndex: ' + result); 785 } 786 }) 787 Button('getParamByNameHomePage', { stateEffect: true, type: ButtonType.Capsule}) 788 .width('50%') 789 .height(40) 790 .margin(20) 791 .onClick(() => { 792 if (this.pageStack !== undefined && this.pageStack !== null) { 793 let result = this.pageStack.getParamByName('PageHome1'); 794 hilog.info(0x0000, 'demotest', 'getParamByName: ' + result.toString()); 795 } 796 }) 797 Button('getIndexByNameHomePage', { stateEffect: true, type: ButtonType.Capsule}) 798 .width('50%') 799 .height(40) 800 .margin(20) 801 .onClick(() => { 802 if (this.pageStack !== undefined && this.pageStack !== null) { 803 let result = this.pageStack.getIndexByName('PageHome1'); 804 hilog.info(0x0000, 'demotest', 'getIndexByName: ' + result); 805 } 806 }) 807 Button('keepBottomPage True', { stateEffect: true, type: ButtonType.Capsule}) 808 .width('50%') 809 .height(40) 810 .margin(10) 811 .onClick(() => { 812 if (this.pageStack !== undefined && this.pageStack !== null) { 813 this.pageStack.keepBottomPage(true); 814 } 815 }) 816 Button('keepBottomPage False', { stateEffect: true, type: ButtonType.Capsule}) 817 .width('50%') 818 .height(40) 819 .margin(10) 820 .onClick(() => { 821 if (this.pageStack !== undefined && this.pageStack !== null) { 822 this.pageStack.keepBottomPage(false); 823 } 824 }) 825 Button('setPlaceholderPage', { stateEffect: true, type: ButtonType.Capsule}) 826 .width('50%') 827 .height(40) 828 .margin(10) 829 .onClick(() => { 830 if (this.pageStack !== undefined && this.pageStack !== null) { 831 this.pageStack.setPlaceholderPage({ name: 'PagePlaceholder' }); 832 } 833 }) 834 }.backgroundColor(0xFFFFFF).width('100%').padding(10).borderRadius(15) 835 } 836 .width('100%') 837 } 838 .width('100%') 839 .height('92%') 840 }.hideTitleBar(true) 841 } 842 } 843 844 log(): boolean { 845 hilog.info(0x0000, 'demotest', 'PageHome1 build called'); 846 return true; 847 } 848} 849``` 850 851```typescript 852// pages/PageDetail1.ets:详情页 853import { MultiNavPathStack, SplitPolicy } from '@ohos.arkui.advanced.MultiNavigation'; 854import { hilog } from '@kit.PerformanceAnalysisKit'; 855 856@Component 857export struct PageDetail1 { 858 @State message: string = 'PageDetail1'; 859 @Consume('pageStack') pageStack: MultiNavPathStack; 860 controller: TextInputController = new TextInputController() 861 text: String = ''; 862 param: Object = new Object(); 863 864 build() { 865 if (this.log()) { 866 NavDestination() { 867 Column() { 868 Column() { 869 Text(this.message) 870 .fontSize(40) 871 .fontWeight(FontWeight.Bold) 872 } 873 .height('8%') 874 .width('100%') 875 Scroll(){ 876 Column(){ 877 Button('OpenHome', { stateEffect: true, type: ButtonType.Capsule}) 878 .width('50%') 879 .height(40) 880 .margin(20) 881 .onClick(() => { 882 if (this.pageStack !== undefined && this.pageStack !== null) { 883 this.pageStack.pushPathByName('PageHome1', 'testParam', true, SplitPolicy.HOME_PAGE); 884 } 885 }) 886 Button('OpenDetail', { stateEffect: true, type: ButtonType.Capsule}) 887 .width('50%') 888 .height(40) 889 .margin(20) 890 .onClick(() => { 891 if (this.pageStack !== undefined && this.pageStack !== null) { 892 this.pageStack.pushPathByName('PageDetail1', 'testParam'); 893 } 894 }) 895 Button('OpenFull', { stateEffect: true, type: ButtonType.Capsule}) 896 .width('50%') 897 .height(40) 898 .margin(20) 899 .onClick(() => { 900 if (this.pageStack !== undefined && this.pageStack !== null) { 901 this.pageStack.pushPathByName('PageFull1', 'testParam', true, SplitPolicy.FULL_PAGE); 902 } 903 }) 904 Button('ReplaceDetail', { stateEffect: true, type: ButtonType.Capsule}) 905 .width('50%') 906 .height(40) 907 .margin(20) 908 .onClick(() => { 909 if (this.pageStack !== undefined && this.pageStack !== null) { 910 this.pageStack.replacePathByName('PageDetail2', 'testParam'); 911 } 912 }) 913 Button('removeByName PageDetail1', { stateEffect: true, type: ButtonType.Capsule}) 914 .width('50%') 915 .height(40) 916 .margin(20) 917 .onClick(() => { 918 if (this.pageStack !== undefined && this.pageStack !== null) { 919 this.pageStack.removeByName('PageDetail1'); 920 } 921 }) 922 Button('removeByIndexes 0135', { stateEffect: true, type: ButtonType.Capsule}) 923 .width('50%') 924 .height(40) 925 .margin(20) 926 .onClick(() => { 927 if (this.pageStack !== undefined && this.pageStack !== null) { 928 this.pageStack.removeByIndexes([0,1,3,5]); 929 } 930 }) 931 Button('switchFullScreenState true', { stateEffect: true, type: ButtonType.Capsule}) 932 .width('50%') 933 .height(40) 934 .margin(20) 935 .onClick(() => { 936 if (this.pageStack !== undefined && this.pageStack !== null) { 937 this.pageStack.switchFullScreenState(true); 938 } 939 }) 940 Button('switchFullScreenState false', { stateEffect: true, type: ButtonType.Capsule}) 941 .width('50%') 942 .height(40) 943 .margin(20) 944 .onClick(() => { 945 if (this.pageStack !== undefined && this.pageStack !== null) { 946 this.pageStack.switchFullScreenState(false); 947 } 948 }) 949 Button('pop', { stateEffect: true, type: ButtonType.Capsule}) 950 .width('50%') 951 .height(40) 952 .margin(20) 953 .onClick(() => { 954 if (this.pageStack !== undefined && this.pageStack !== null) { 955 this.pageStack.pop('123'); 956 } 957 }) 958 Button('popToHome1', { stateEffect: true, type: ButtonType.Capsule}) 959 .width('50%') 960 .height(40) 961 .margin(20) 962 .onClick(() => { 963 if (this.pageStack !== undefined && this.pageStack !== null) { 964 this.pageStack.popToName('PageHome1'); 965 } 966 }) 967 TextInput({placeholder: 'input your poptoindex ...', controller: this.controller }) 968 .placeholderColor(Color.Grey) 969 .placeholderFont({ size: 14, weight: 400 }) 970 .caretColor(Color.Blue) 971 .type(InputType.Number) 972 .width('50%') 973 .height(40) 974 .margin(20) 975 .fontSize(14) 976 .fontColor(Color.Black) 977 .onChange((value: String) => { 978 this.text = value 979 }) 980 Button('poptoindex', { stateEffect: true, type: ButtonType.Capsule}) 981 .width('50%') 982 .height(40) 983 .margin(20) 984 .onClick(() => { 985 if (this.pageStack !== undefined && this.pageStack !== null) { 986 this.pageStack.popToIndex(Number(this.text)); 987 this.controller.caretPosition(1) 988 } 989 }) 990 Button('moveIndexToTop', { stateEffect: true, type: ButtonType.Capsule}) 991 .width('50%') 992 .height(40) 993 .margin(20) 994 .onClick(() => { 995 if (this.pageStack !== undefined && this.pageStack !== null) { 996 this.pageStack.moveIndexToTop(Number(this.text)); 997 this.controller.caretPosition(1) 998 } 999 }) 1000 Button('clear', { stateEffect: true, type: ButtonType.Capsule}) 1001 .width('50%') 1002 .height(40) 1003 .margin(20) 1004 .onClick(() => { 1005 if (this.pageStack !== undefined && this.pageStack !== null) { 1006 this.pageStack.clear(); 1007 } 1008 }) 1009 Button('disableAnimation', { stateEffect: true, type: ButtonType.Capsule}) 1010 .width('50%') 1011 .height(40) 1012 .margin(20) 1013 .onClick(() => { 1014 if (this.pageStack !== undefined && this.pageStack !== null) { 1015 this.pageStack.disableAnimation(true); 1016 } 1017 }) 1018 Button('enableAnimation', { stateEffect: true, type: ButtonType.Capsule}) 1019 .width('50%') 1020 .height(40) 1021 .margin(20) 1022 .onClick(() => { 1023 if (this.pageStack !== undefined && this.pageStack !== null) { 1024 this.pageStack.disableAnimation(false); 1025 } 1026 }) 1027 Button('setHomeWidthRange(20, 80)', { stateEffect: true, type: ButtonType.Capsule}) 1028 .width('50%') 1029 .height(40) 1030 .margin(20) 1031 .onClick(() => { 1032 if (this.pageStack !== undefined && this.pageStack !== null) { 1033 this.pageStack.setHomeWidthRange(20, 80); 1034 } 1035 }) 1036 Button('setHomeWidthRange(-1, 20)', { stateEffect: true, type: ButtonType.Capsule}) 1037 .width('50%') 1038 .height(40) 1039 .margin(20) 1040 .onClick(() => { 1041 if (this.pageStack !== undefined && this.pageStack !== null) { 1042 this.pageStack.setHomeWidthRange(-1, 20); 1043 } 1044 }) 1045 Button('setHomeWidthRange(20, 120)', { stateEffect: true, type: ButtonType.Capsule}) 1046 .width('50%') 1047 .height(40) 1048 .margin(20) 1049 .onClick(() => { 1050 if (this.pageStack !== undefined && this.pageStack !== null) { 1051 this.pageStack.setHomeWidthRange(20, 120); 1052 } 1053 }) 1054 } 1055 .width('100%') 1056 } 1057 .width('100%') 1058 .height('92%') 1059 } 1060 }.hideTitleBar(true) 1061 } 1062 } 1063 1064 log(): boolean { 1065 hilog.info(0x0000, 'demotest', 'PageDetail1 build called'); 1066 return true; 1067 } 1068} 1069``` 1070 1071```typescript 1072// pages/PageDetail2.ets: 详情页 1073import { MultiNavPathStack, SplitPolicy } from '@ohos.arkui.advanced.MultiNavigation'; 1074import { hilog } from '@kit.PerformanceAnalysisKit'; 1075 1076@Component 1077export struct PageDetail2 { 1078 @State message: string = 'PageDetail2'; 1079 @Consume('pageStack') pageStack: MultiNavPathStack; 1080 controller: TextInputController = new TextInputController() 1081 text: String = ''; 1082 param: Object = new Object(); 1083 1084 build() { 1085 if (this.log()) { 1086 NavDestination() { 1087 Column() { 1088 Column() { 1089 Text(this.message) 1090 .fontSize(40) 1091 .fontWeight(FontWeight.Bold) 1092 } 1093 .width('100%') 1094 .height('8%') 1095 Scroll(){ 1096 Column() { 1097 Button('OpenHome', { stateEffect: true, type: ButtonType.Capsule}) 1098 .width('50%') 1099 .height(40) 1100 .margin(20) 1101 .onClick(() => { 1102 if (this.pageStack !== undefined && this.pageStack !== null) { 1103 this.pageStack.pushPathByName('PageHome1', 'testParam', true, SplitPolicy.HOME_PAGE); 1104 } 1105 }) 1106 Button('OpenDetail', { stateEffect: true, type: ButtonType.Capsule}) 1107 .width('50%') 1108 .height(40) 1109 .margin(20) 1110 .onClick(() => { 1111 if (this.pageStack !== undefined && this.pageStack !== null) { 1112 this.pageStack.pushPathByName('PageDetail1', 'testParam'); 1113 } 1114 }) 1115 Button('OpenFull', { stateEffect: true, type: ButtonType.Capsule}) 1116 .width('50%') 1117 .height(40) 1118 .margin(20) 1119 .onClick(() => { 1120 if (this.pageStack !== undefined && this.pageStack !== null) { 1121 this.pageStack.pushPathByName('PageFull1', 'testParam', true, SplitPolicy.FULL_PAGE); 1122 } 1123 }) 1124 Button('ReplaceDetail', { stateEffect: true, type: ButtonType.Capsule}) 1125 .width('50%') 1126 .height(40) 1127 .margin(20) 1128 .onClick(() => { 1129 if (this.pageStack !== undefined && this.pageStack !== null) { 1130 this.pageStack.replacePathByName('PageDetail2', 'testParam'); 1131 } 1132 }) 1133 TextInput({placeholder: 'input your poptoindex ...', controller: this.controller }) 1134 .placeholderColor(Color.Grey) 1135 .placeholderFont({ size: 14, weight: 400 }) 1136 .caretColor(Color.Blue) 1137 .type(InputType.Number) 1138 .width('50%') 1139 .height(40) 1140 .margin(20) 1141 .fontSize(14) 1142 .fontColor(Color.Black) 1143 .onChange((value: String) => { 1144 this.text = value 1145 }) 1146 Button('moveIndexToTop', { stateEffect: true, type: ButtonType.Capsule}) 1147 .width('50%') 1148 .height(40) 1149 .margin(20) 1150 .onClick(() => { 1151 if (this.pageStack !== undefined && this.pageStack !== null) { 1152 this.pageStack.moveIndexToTop(Number(this.text)); 1153 this.controller.caretPosition(1) 1154 } 1155 }) 1156 Button('pop', { stateEffect: true, type: ButtonType.Capsule}) 1157 .width('50%') 1158 .height(40) 1159 .margin(20) 1160 .onClick(() => { 1161 if (this.pageStack !== undefined && this.pageStack !== null) { 1162 this.pageStack.pop(); 1163 } 1164 }) 1165 TextInput({placeholder: 'input your poptoindex ...', controller: this.controller }) 1166 .placeholderColor(Color.Grey) 1167 .placeholderFont({ size: 14, weight: 400 }) 1168 .caretColor(Color.Blue) 1169 .type(InputType.Number) 1170 .width('50%') 1171 .height(40) 1172 .margin(20) 1173 .fontSize(14) 1174 .fontColor(Color.Black) 1175 .onChange((value: String) => { 1176 this.text = value 1177 }) 1178 Button('poptoindex', { stateEffect: true, type: ButtonType.Capsule}) 1179 .width('50%') 1180 .height(40) 1181 .margin(20) 1182 .onClick(() => { 1183 if (this.pageStack !== undefined && this.pageStack !== null) { 1184 this.pageStack.popToIndex(Number(this.text)); 1185 this.controller.caretPosition(1) 1186 } 1187 }) 1188 Button('clear', { stateEffect: true, type: ButtonType.Capsule}) 1189 .width('50%') 1190 .height(40) 1191 .margin(20) 1192 .onClick(() => { 1193 if (this.pageStack !== undefined && this.pageStack !== null) { 1194 this.pageStack.clear(); 1195 } 1196 }) 1197 Button('disableAnimation', { stateEffect: true, type: ButtonType.Capsule}) 1198 .width('50%') 1199 .height(40) 1200 .margin(20) 1201 .onClick(() => { 1202 if (this.pageStack !== undefined && this.pageStack !== null) { 1203 this.pageStack.disableAnimation(true); 1204 } 1205 }) 1206 Button('enableAnimation', { stateEffect: true, type: ButtonType.Capsule}) 1207 .width('50%') 1208 .height(40) 1209 .margin(20) 1210 .onClick(() => { 1211 if (this.pageStack !== undefined && this.pageStack !== null) { 1212 this.pageStack.disableAnimation(false); 1213 } 1214 }) 1215 } 1216 .width('100%') 1217 } 1218 .width('100%') 1219 .height('92%') 1220 } 1221 } 1222 .hideTitleBar(true) 1223 } 1224 } 1225 1226 log(): boolean { 1227 hilog.info(0x0000, 'demotest', 'PageDetail2 build called'); 1228 return true; 1229 } 1230} 1231``` 1232 1233```typescript 1234// pages/PageFull1.ets: 不参与分栏的页面,默认全屏展示 1235import { MultiNavPathStack, SplitPolicy } from '@ohos.arkui.advanced.MultiNavigation'; 1236import { hilog } from '@kit.PerformanceAnalysisKit'; 1237 1238@Component 1239export struct PageFull1 { 1240 @State message: string = 'PageFull1'; 1241 @Consume('pageStack') pageStack: MultiNavPathStack; 1242 controller: TextInputController = new TextInputController() 1243 text: String = ''; 1244 1245 build() { 1246 if (this.log()) { 1247 NavDestination() { 1248 Column() { 1249 Column() { 1250 Text(this.message) 1251 .fontSize(40) 1252 .fontWeight(FontWeight.Bold) 1253 } 1254 .width('100%') 1255 .height('8%') 1256 1257 Scroll() { 1258 Column() { 1259 Button('OpenHome', { stateEffect: true, type: ButtonType.Capsule }) 1260 .width('50%') 1261 .height(40) 1262 .margin(20) 1263 .onClick(() => { 1264 if (this.pageStack !== undefined && this.pageStack !== null) { 1265 this.pageStack.pushPathByName('PageHome1', 'testParam', true, SplitPolicy.HOME_PAGE); 1266 } 1267 }) 1268 Button('OpenDetail', { stateEffect: true, type: ButtonType.Capsule }) 1269 .width('50%') 1270 .height(40) 1271 .margin(20) 1272 .onClick(() => { 1273 if (this.pageStack !== undefined && this.pageStack !== null) { 1274 this.pageStack.pushPathByName('PageDetail1', 'testParam'); 1275 } 1276 }) 1277 Button('OpenFull', { stateEffect: true, type: ButtonType.Capsule }) 1278 .width('50%') 1279 .height(40) 1280 .margin(20) 1281 .onClick(() => { 1282 if (this.pageStack !== undefined && this.pageStack !== null) { 1283 this.pageStack.pushPathByName('PageFull1', 'testParam', true, SplitPolicy.FULL_PAGE); 1284 } 1285 }) 1286 Button('ReplaceFULL', { stateEffect: true, type: ButtonType.Capsule }) 1287 .width('50%') 1288 .height(40) 1289 .margin(20) 1290 .onClick(() => { 1291 if (this.pageStack !== undefined && this.pageStack !== null) { 1292 this.pageStack.replacePathByName('PageFull1', 'testParam', true); 1293 } 1294 }) 1295 Button('removeByName PageFull1', { stateEffect: true, type: ButtonType.Capsule }) 1296 .width('50%') 1297 .height(40) 1298 .margin(20) 1299 .onClick(() => { 1300 if (this.pageStack !== undefined && this.pageStack !== null) { 1301 this.pageStack.removeByName('PageFull1'); 1302 } 1303 }) 1304 Button('removeByIndexes 0135', { stateEffect: true, type: ButtonType.Capsule }) 1305 .width('50%') 1306 .height(40) 1307 .margin(20) 1308 .onClick(() => { 1309 if (this.pageStack !== undefined && this.pageStack !== null) { 1310 this.pageStack.removeByIndexes([0, 1, 3, 5]); 1311 } 1312 }) 1313 Button('pop', { stateEffect: true, type: ButtonType.Capsule }) 1314 .width('50%') 1315 .height(40) 1316 .margin(20) 1317 .onClick(() => { 1318 if (this.pageStack !== undefined && this.pageStack !== null) { 1319 this.pageStack.pop(); 1320 } 1321 }) 1322 TextInput({ placeholder: 'input your poptoindex ...', controller: this.controller }) 1323 .placeholderColor(Color.Grey) 1324 .placeholderFont({ size: 14, weight: 400 }) 1325 .caretColor(Color.Blue) 1326 .width('50%') 1327 .height(40) 1328 .margin(20) 1329 .type(InputType.Number) 1330 .fontSize(14) 1331 .fontColor(Color.Black) 1332 .onChange((value: String) => { 1333 this.text = value 1334 }) 1335 Button('poptoindex', { stateEffect: true, type: ButtonType.Capsule }) 1336 .width('50%') 1337 .height(40) 1338 .margin(20) 1339 .onClick(() => { 1340 if (this.pageStack !== undefined && this.pageStack !== null) { 1341 this.pageStack.popToIndex(Number(this.text)); 1342 this.controller.caretPosition(1) 1343 } 1344 }) 1345 } 1346 .width('100%') 1347 } 1348 .width('100%') 1349 .height('92%') 1350 } 1351 } 1352 .hideTitleBar(true) 1353 .onBackPressed(() => { 1354 hilog.info(0x0000, 'demotest', 'PageFull1 onBackPressed: '); 1355 return false; 1356 }) 1357 } 1358 } 1359 1360 log(): boolean { 1361 hilog.info(0x0000, 'demotest', 'PageFull1 build called'); 1362 return true; 1363 } 1364} 1365``` 1366 1367```typescript 1368// pages/PagePlaceholder.ets: 占位页 1369import { MultiNavPathStack, SplitPolicy } from '@ohos.arkui.advanced.MultiNavigation'; 1370import { hilog } from '@kit.PerformanceAnalysisKit'; 1371 1372@Component 1373export struct PagePlaceholder { 1374 @State message: string = 'PagePlaceholder'; 1375 @Consume('pageStack') pageStack: MultiNavPathStack; 1376 controller: TextInputController = new TextInputController() 1377 text: String = ''; 1378 lastBackTime: number = 0; 1379 1380 build() { 1381 if (this.log()) { 1382 NavDestination() { 1383 Column() { 1384 Column() { 1385 Text(this.message) 1386 .fontSize(50) 1387 .fontWeight(FontWeight.Bold) 1388 } 1389 .width('100%') 1390 .height('8%') 1391 1392 Stack({alignContent: Alignment.Center}) { 1393 Text('Placeholder示例页面') 1394 .fontSize(80) 1395 .fontWeight(FontWeight.Bold) 1396 .fontColor(Color.Red) 1397 } 1398 .width('100%') 1399 .height('92%') 1400 } 1401 }.hideTitleBar(true) 1402 } 1403 } 1404 1405 log(): boolean { 1406 hilog.info(0x0000, 'demotest', 'PagePlaceholder build called'); 1407 return true; 1408 } 1409} 1410```