# ohos_multi_navigation
**Repository Path**: openharmony-sig/ohos_multi_navigation
## Basic Information
- **Project Name**: ohos_multi_navigation
- **Description**: 提供高级分栏组件,给三方应用快速接入大尺寸设备的方案
- **Primary Language**: Unknown
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: https://gitee.com/openharmony-sig/ohos_multi_navigation
- **GVP Project**: No
## Statistics
- **Stars**: 5
- **Forks**: 10
- **Created**: 2024-04-23
- **Last Updated**: 2025-09-05
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 🚨 **重要提示 | IMPORTANT**
>
> **⚠️ 此代码仓已归档。新地址请访问 [ohos_multi_navigation](https://gitcode.com/openharmony-sig/ohos_multi_navigation)。| ⚠️ This repository has been archived. For the new address, please visit [ohos_multi_navigation](https://gitcode.com/openharmony-sig/ohos_multi_navigation).**
>
---
>
# ohos_multi_navigation
## 介绍
提供高级分栏组件,给三方应用快速接入大尺寸设备的方案
## 下载安装
```shell
ohpm install @ohos/multinavigation
```
OpenHarmony ohpm 环境配置等更多内容,请参考[如何安装 OpenHarmony ohpm 包](https://gitee.com/openharmony-tpc/docs/blob/master/OpenHarmony_har_usage.md)
## 规格说明
1.高级分栏组件支持多主页,可以通过[pushPath](#pushpath)等接口将多个主页入栈,以获取更好体验。
2.高级分栏组件默认支持左起右清栈规格,即点击左侧的主页拉起详情页,会将右侧其它详情页清空,然后右侧显示详情页;而在右侧详情页再次拉起详情页则不会清栈。
3.高级分栏组件支持将单个详情页临时切换为全屏显示,详见[switchFullScreen](#switchfullscreen)接口。
4.高级分栏组件推荐应用主页适配横屏显示,以在大屏设备上获得更好的用户体验,同时也提供PlaceHolder支持默认分栏显示,详见[setPlaceHolder](#setplaceholderpage)接口。
5.平板横屏时支持分栏显示,平板竖屏时不支持分栏显示。
6.在折叠屏展开态下,已经分栏之后默认都是分栏显示,不区分横屏竖屏。
## 适配说明
1.本组件从API12开始支持。
2.应用主页需要用NavDestination包装,具体可参考demo示例。
3.clear和pop接口默认会将主页也出栈,如若要保留栈底页面,可以使用[setKeepBottomPage](#setkeepbottompage)接口。
4.由于栈嵌套原因,当前主页的onBackPressed回调会先于详情页,为了功能正常,需要应用不捕获onBackPressed回调,或者参考demo示例对当前栈的数量做出判断再捕获回调。
**特别说明:**
由于高级分栏组件存在多重栈嵌套,调用本文档明确说明的不支持接口或不在本文档支持接口列表中的接口(例如getParent、setInterception、pushDestination等),可能会发生无法预期的问题。
MultiNavPathStack目前仅支持使用方自行创建,不支持通过回调拿到,不要使用NavDestination的onReady等类似事件或接口来拿到NavPathStack进行栈操作,可能会发生无法预期的问题。
## 使用说明
1.提供了应用分栏组件MultiNavigation及MultiNavPathStack路由栈作为分栏时存储页面使用。
2.以MultiNavigation组件及配合MultiNavPathStack路由栈来实现应用分栏操作举例:
**注:**
PageHome:主页
PageDetail:详情页
PageFull:不参与分栏的页面,默认全屏展示
```typescript
import { MultiNavigation, MultiNavPathStack, SplitPolicy } from '@ohos/multinavigation';
import { PageDetail1 } from './PageDetail1';
import { PageFull1 } from './PageFull1';
import { PageHome1 } from './PageHome1';
@Entry
@Component
struct Index {
@Provide('pageStack')pageStack: MultiNavPathStack = new MultiNavPathStack();
@Builder
PageMap(name: string, param?: object) {
if (name === 'PageHome1') {
PageHome1()
} else if (name === 'PageDetail1') {
PageDetail1();
} else if (name == 'PageFull1') {
PageFull1();
}
}
aboutToAppear(): void {
this.pageStack.pushPath({ name : 'PageHome1', param: "paramTest"}, false, SplitPolicy.HOME_PAGE);
}
build() {
Column() {
Row() {
MultiNavigation({navDestination: this.PageMap, multiStack: this.pageStack})
}
.width('100%')
}
}
}
```
PageHome1
```typescript
import { hilog } from '@kit.PerformanceAnalysisKit';
@Component
export struct PageHome1 {
@State message: string = 'PageHome1';
@Consume('pageStack') pageStack: MultiNavPathStack;
build() {
if (this.log()) {
NavDestination() {
Column() {
Button('OpenDetail', { stateEffect: true, type: ButtonType.Capsule})
.width('50%')
.height(40)
.margin(20)
.onClick(() => {
if (this.pageStack !== undefined && this.pageStack !== null) {
this.pageStack.pushPath({ name: 'PageDetail1' });
}
})
Button('pop', { stateEffect: true, type: ButtonType.Capsule})
.width('50%')
.height(40)
.margin(20)
.onClick(() => {
if (this.pageStack !== undefined && this.pageStack !== null) {
this.pageStack.pop();
}
})
}
}
.hideTitleBar(true)
}
}
log(): boolean {
hilog.info(0x0000, 'demotest', 'PageHome1 build called');
return true;
}
}
```
PageDetail1:
```typescript
import { MultiNavPathStack, SplitPolicy } from '@ohos/multinavigation';
import { hilog } from '@kit.PerformanceAnalysisKit';
@Component
export struct PageDetail1 {
@State message: string = 'PageDetail1';
@Consume('pageStack') pageStack: MultiNavPathStack;
build() {
if (this.log()) {
NavDestination() {
Column() {
Scroll(){
Column(){
Button('pop', { stateEffect: true, type: ButtonType.Capsule})
.width('50%')
.height(40)
.margin(20)
.onClick(() => {
if (this.pageStack !== undefined && this.pageStack !== null) {
this.pageStack.pop();
}
})
Button('OpenFull', { stateEffect: true, type: ButtonType.Capsule})
.width('50%')
.height(40)
.margin(20)
.onClick(() => {
if (this.pageStack !== undefined && this.pageStack !== null) {
this.pageStack.pushPath({ name: 'PageFull1' }, true, SplitPolicy.FULL_PAGE);
}
})
}
}
.height('100%')
}
}
.hideTitleBar(true)
}
}
log(): boolean {
hilog.info(0x0000, 'demotest', 'PageDetail1 build called');
return true;
}
}
```
PageFull1:
```typescript
import { MultiNavPathStack, SplitPolicy } from '@ohos/multinavigation';
import { hilog } from '@kit.PerformanceAnalysisKit';
@Component
export struct PageFull1 {
@State message: string = 'PageFull1';
@Consume('pageStack') pageStack: MultiNavPathStack;
build() {
if (this.log()) {
NavDestination() {
Column() {
Button('OpenHome', { stateEffect: true, type: ButtonType.Capsule})
.width('50%')
.height(40)
.margin(20)
.onClick(() => {
if (this.pageStack !== undefined && this.pageStack !== null) {
this.pageStack.pushPath({ name: 'PageHome1', param: 'open from full' }, true, SplitPolicy.HOME_PAGE);
}
})
Button('pop', { stateEffect: true, type: ButtonType.Capsule})
.width('50%')
.height(40)
.margin(20)
.onClick(() => {
if (this.pageStack !== undefined && this.pageStack !== null) {
this.pageStack.pop();
}
})
}
}
.hideTitleBar(true)
}
}
log(): boolean {
hilog.info(0x0000, 'demotest', 'PageFull1 build called');
return true;
}
}
```
## 组件说明
## MultiNavigation
### 子组件
不可以包含子组件
推荐使用[MultiNavPathStack](#multinavpathstack)配合NavDestination组件进行页面路由。
### 接口
MultiNavigation(navDestination: navDestination, multiStack: MultiNavPathStack)
绑定路由栈到MultiNavigation组件。
**参数:**
| 参数名 | 参数类型 | 必填 | 参数描述 |
|:---------:|:----------------------:|-----| ------ |
| pathInfos | [MultiNavPathStack](#multinavpathstack) | 是 | 路由栈信息。 |
### 属性
不支持任何属性
### 事件
#### onNavigationModeChange
onNavigationModeChange(callback: (mode: NavigationMode) => void)
当Navigation首次显示或者单双栏状态发生变化时触发该回调。
**参数:**
| 名称 | 类型 | 必填 | 描述 |
|:---------------------:|:------------:|:------:|---------|
| mode | [NavigationMode](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#navigationmode9枚举说明) | 是 | NavigationMode.Split: 当前Navigation显示为双栏;
NavigationMode.Stack: 当前Navigation显示为单栏。 |
#### onHomeShowInTop
onHomeShowInTop(callback: (name: string) => void)
当通过pop等接口使得主页在栈顶时会触发该回调。
**参数**
| 名称 | 类型 | 必填 | 描述 |
|:---------------------:|:------------:|:------:|---------|
| name | string | 是 | 主页页面名称。 |
### MultiNavPathStack
MultiNavigation路由栈。
#### pushPath
pushPath(info: NavPathInfo, animated?: boolean, policy?: SplitPolicy): void
将info指定的NavDestination页面信息入栈。
**参数:**
| 名称 | 类型 | 必填 | 描述 |
|:---------:|:------------------------------:|----|----------------------|
| info | [NavPathInfo](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#navpathinfo10) | 是 | NavDestination页面的信息。 |
| animated | boolean | 否 | 是否支持转场动画,默认值:true。 |
| policy | [SplitPolicy](#splitpolicy枚举类型) | 否 | 当前入栈页面的策略,默认值:DETAIL_PAGE |
#### pushPathByName
pushPathByName(name: string, param: Object, animated?: boolean, policy?: SplitPolicy): void
将name指定的NavDestination页面信息入栈,传递的数据为param。
**参数:**
| 名称 | 类型 | 必填 | 描述 |
|:---------------------:|:------------:|:------:| --------------------- |
| name | string | 是 | NavDestination页面名称。 |
| param | Object | 是 | NavDestination页面详细参数。 |
| animated | boolean | 否 | 是否支持转场动画,默认值:true。 |
| policy | [SplitPolicy](#splitpolicy枚举类型) | 否 | 当前入栈页面的策略,默认值:DETAIL_PAGE |
#### pushPathByName
pushPathByName(name: string, param: Object, onPop: import('../api/@ohos.base').Callback\, animated?: boolean, policy?: SplitPolicy): void
将name指定的NavDestination页面信息入栈,传递的数据为param,添加onPop回调接收入栈页面出栈时的返回结果,并进行处理。
**参数:**
| 名称 | 类型 | 必填 | 描述 |
|:---------:|:-------------------------------------------------------------:|:------:|------|
| name | string | 是 | NavDestination页面名称。 |
| param | Object | 是 | NavDestination页面详细参数。 |
| onPop | import('../api/@ohos.base').Callback\<[PopInfo](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#popinfo11)> | 是 | Callback回调,用于页面出栈时触发该回调处理返回结果。 |
| animated | boolean | 否 | 是否支持转场动画,默认值:true。 |
| policy | [SplitPolicy](#splitpolicy枚举类型) | 否 | 当前入栈页面的策略,默认值:DETAIL_PAGE |
#### replacePath
replacePath(info: NavPathInfo, animated?: boolean): void
将当前页面栈栈顶退出,将info指定的NavDestination页面信息入栈,新页面的分栏策略继承原栈顶页面的策略。
**参数:**
| 名称 | 类型 | 必填 | 描述 |
|:--------:|:-------------------------------:| ---- | -------------------- |
| info | [NavPathInfo](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#navpathinfo10) | 是 | 新栈顶页面参数信息 |
| animated | boolean | 否 | 是否支持转场动画,默认值:true。 |
#### replacePathByName
replacePathByName(name: string, param: Object, animated?: boolean): void
将当前页面栈栈顶退出,将name指定的页面入栈,新页面的分栏策略继承原栈顶页面的策略。
**参数:**
| 名称 | 类型 | 必填 | 描述 |
|:--------:|:---------:|:------:|----------------------|
| name | string | 是 | NavDestination页面名称。 |
| param | Object | 是 | NavDestination页面详细参数。 |
| animated | boolean | 否 | 是否支持转场动画,默认值:true。 |
#### removeByIndexes
removeByIndexes(indexes: Array): number
将页面栈内索引值在indexes中的NavDestination页面删除。
**参数:**
| 名称 | 类型 | 必填 | 描述 |
|:--------:|:---------------:|:------:| --------------------- |
| indexes | Array | 是 | 待删除NavDestination页面的索引值数组。 |
**返回值:**
| 类型 | 说明 |
|:-------------:| ------------------------ |
| number | 返回删除的NavDestination页面数量。 |
#### removeByName
removeByName(name: string): number
将页面栈内指定name的NavDestination页面删除。
**参数:**
| 名称 | 类型 | 必填 | 描述 |
|:-------:| ------- | ---- | --------------------- |
| name | string | 是 | 删除的NavDestination页面的名字。 |
**返回值:**
| 类型 | 说明 |
|:-------------:| ------------------------ |
| number | 返回删除的NavDestination页面数量。 |
#### pop
pop(animated?: boolean): NavPathInfo | undefined
弹出路由栈栈顶元素。
>**说明**
>
> 当调用[setKeepBottomPage](#setkeepbottompage)接口并设置为true时,会保留栈底页面。
**参数:**
| 名称 | 类型 | 必填 | 描述 |
|:-----------:|:--------:|:------:| -------------------- |
| animated | boolean | 否 | 是否支持转场动画,默认值:true。 |
**返回值:**
| 类型 | 说明 |
| ----------- | ------------------------ |
| [NavPathInfo](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#navpathinfo10) | 返回栈顶NavDestination页面的信息。 |
| undefined | 当路由栈为空时返回undefined。 |
#### pop
pop(result: Object, animated?: boolean): NavPathInfo | undefined
弹出路由栈栈顶元素,并触发onPop回调传入页面处理结果。
>**说明**
>
> 当调用[setKeepBottomPage](#setkeepbottompage)接口并设置为true时,会保留栈底页面。
**参数:**
| 名称 | 类型 | 必填 | 描述 |
|:---------:|:-------------------------------:|:------:| -------------------- |
| result | Object | 是 | 页面自定义处理结果。 |
| animated | boolean | 否 | 是否支持转场动画,默认值:true。 |
**返回值:**
| 类型 | 说明 |
| ----------- | ------------------------ |
| [NavPathInfo](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md#navpathinfo10) | 返回栈顶NavDestination页面的信息。 |
| undefined | 当路由栈为空时返回undefined。 |
#### popToName
popToName(name: string, animated?: boolean): number
回退路由栈到由栈底开始第一个名为name的NavDestination页面。
**参数:**
| 名称 | 类型 | 必填 | 描述 |
|:----------:|:--------:|:------:| ------------------- |
| name | string | 是 | NavDestination页面名称。 |
| animated | boolean | 否 | 是否支持转场动画,默认值:true。 |
**返回值:**
| 类型 | 说明 |
| ------ | ---------------------------------------- |
| number | 如果栈中存在名为name的NavDestination页面,则返回由栈底开始第一个名为name的NavDestination页面的索引,否则返回-1。 |
#### popToName
popToName(name: string, result: Object, animated?: boolean): number
回退路由栈到由栈底开始第一个名为name的NavDestination页面,并触发onPop回调传入页面处理结果。
**参数:**
| 名称 | 类型 | 必填 | 描述 |
|:---------:|:--------:|:------:| ------------------- |
| name | string | 是 | NavDestination页面名称。 |
| result | Object | 是 | 页面自定义处理结果。 |
| animated | boolean | 否 | 是否支持转场动画,默认值:true。 |
**返回值:**
| 类型 | 说明 |
| ------ | ---------------------------------------- |
| number | 如果栈中存在名为name的NavDestination页面,则返回由栈底开始第一个名为name的NavDestination页面的索引,否则返回-1。 |
#### popToIndex
popToIndex(index: number, animated?: boolean): void
回退路由栈到index指定的NavDestination页面。
**参数:**
| 名称 | 类型 | 必填 | 描述 |
|:------------:|:--------:|:------:| ---------------------- |
| index | number | 是 | NavDestination页面的位置索引。 |
| animated | boolean | 否 | 是否支持转场动画,默认值:true。 |
#### popToIndex
popToIndex(index: number, result: Object, animated?: boolean): void
回退路由栈到index指定的NavDestination页面,并触发onPop回调传入页面处理结果。
**参数:**
| 名称 | 类型 | 必填 | 描述 |
| ----- | ------ | ---- | ---------------------- |
| index | number | 是 | NavDestination页面的位置索引。 |
| result | Object | 是 | 页面自定义处理结果。 |
| animated | boolean | 否 | 是否支持转场动画,默认值:true。 |
#### moveToTop
moveToTop(name: string, animated?: boolean): number
将由栈底开始第一个名为name的NavDestination页面移到栈顶。
> **说明:**
>
> 高级分栏组件存在主页和详情页的关联关系,以及多主页多重栈的情况,会有以下场景和处理策略:
>
> 1)当找到的是最上层主页或者全屏页,此时不做任何处理;
>
> 2)当找到的是最上层主页对应的详情页,则会将对应的的详情页移到栈顶;
>
> 3)当找到的是非最上层的主页,则会将主页和对应所有详情页移到栈顶,详情页相对栈关系不变;
>
> 4)当找到的是非最上层的详情页,则会将主页和对应所有详情页移到栈顶,且将目标详情页移动到对应所有详情页的栈顶;
>
> 5)当找到的是非最上层的全屏页,则会将全屏页移动到栈顶。
| 名称 | 类型 | 必填 | 描述 |
|:---------:|:--------:|:------:| ------------------- |
| name | string | 是 | NavDestination页面名称。 |
| animated | boolean | 否 | 是否支持转场动画,默认值:true。 |
**返回值:**
| 类型 | 说明 |
|:--------:|:----------------------------------------------------------------------------:|
| number | 如果栈中存在名为name的NavDestination页面,则返回由栈底开始第一个名为name的NavDestination页面的索引,否则返回-1。 |
#### moveIndexToTop
moveIndexToTop(index: number, animated?: boolean): void
将指定index的NavDestination页面移到栈顶。
> **说明:**
>
> 高级分栏组件存在主页和详情页的关联关系,以及多主页多重栈的情况,会有以下场景和处理策略:
>
> 1)当找到的是最上层主页或者全屏页,此时不做任何处理;
>
> 2)当找到的是最上层主页对应的详情页,则会将对应的的详情页移到栈顶;
>
> 3)当找到的是非最上层的主页,则会将主页和对应所有详情页移到栈顶,详情页相对栈关系不变;
>
> 4)当找到的是非最上层的详情页,则会将主页和对应所有详情页移到栈顶,且将目标详情页移动到对应所有详情页的栈顶;
>
> 5)当找到的是非最上层的全屏页,则会将全屏页移动到栈顶。
| 名称 | 类型 | 必填 | 描述 |
|:---------:|:-------:|:------:| ------------------- |
| index | number | 是 | NavDestination页面的位置索引。 |
| animated | boolean | 否 | 是否支持转场动画,默认值:true。 |
#### clear
clear(animated?: boolean): void
清除栈中所有页面。
>**说明**
>
> 当调用[setKeepBottomPage](#setkeepbottompage)接口并设置为true时,会保留栈底页面。
**参数:**
| 名称 | 类型 | 必填 | 描述 |
|:---------:|:--------:|:------:| ---------------------- |
| animated | boolean | 否 | 是否支持转场动画,默认值:true。 |
#### getAllPathName
getAllPathName(): Array
获取栈中所有NavDestination页面的名称。
**返回值:**
| 类型 | 说明 |
|:----------------:| -------------------------- |
| Array | 返回栈中所有NavDestination页面的名称。 |
#### getParamByIndex
getParamByIndex(index: number): Object | undefined
获取index指定的NavDestination页面的参数信息。
**参数:**
| 名称 | 类型 | 必填 | 描述 |
|:-------:|:--------:|:------:| ---------------------- |
| index | number | 是 | NavDestination页面的位置索引。 |
**返回值:**
| 类型 | 说明 |
| --------- | -------------------------- |
| Object | 返回对应NavDestination页面的参数信息。 |
| undefined | 传入index无效是返回undefined。|
#### getParamByName
getParamByName(name: string): Array