HarmonyOS 鸿蒙Next Navigation分栏模式下 如何设置右侧的默认显示内容
HarmonyOS 鸿蒙Next Navigation分栏模式下 如何设置右侧的默认显示内容
是否可以在没有二级页面时,为右侧区域设置一个自定义UI样式,比如一个占位图或之类的。
不支持给空白页自定义 UI 样式。
但是,在分栏模式下,可以定义一个表示空页面占位图的 NavDestination 子页面。然后在 Navigation 组件所在页的 aboutToAppear() 方法中通过 this.navPathStack.pushPath() 可设置右侧默认展示页面,可实现类似效果。
有以下两种解决方案
方案一:在 Navigation 的 onNavigationModeChange 事件内判断是否分栏,分栏则 push 默认 NavDestination 入栈显示。参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-basic-components-navigation-V5#onnavigationmodechange11
方案二:提前获取屏幕宽度(页面的 aboutToAppear),判断该宽度下是否需要分栏,需要则 push 默认 NavDestination 入栈显示。对比方案一,可快速显示子组件内容。具体宽度参数可参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-basic-components-navigation-V5#navigationmode9枚举说明
在 Split 模式下如果路由栈内存在一个页面,此时按返回按钮会直接退出应用,不会使右侧变空白。但是与你的需求还是存在一定差距。
目前可以通过自定义派生类继承 NavPathStack 和对 NavDestination 的 onBackPressed() 事件回调进行处理,实现类似的效果,但会有一点繁琐,可以参考一下。
NavigationExample.ets
// 自定义 NavPathStack 派生类
export class DerivedNavPathStack extends NavPathStack {
// 传递 NavigationMode 属性
mode: NavigationMode = NavigationMode.Stack;
// 自定义返回事件回调
customBack(): boolean {
if (this.size() > 1 || this.mode === NavigationMode.Stack) {
return false;
} else {
this.pop();
this.pushPath({ name: 'EmptyPage' });
return true;
}
}
}
[@Entry](/user/Entry)
[@Component](/user/Component)
struct NavigationExample {
private arr: number[] = [0, 1, 2, 3, 4, 5];
[@State](/user/State) naviStack: DerivedNavPathStack = new DerivedNavPathStack();
build() {
Column() {
Navigation(this.naviStack) {
Row() {
Column() {
TextInput({ placeholder: 'search...' })
.width('90%')
.height(40)
.backgroundColor('#FFFFFF')
.margin({ top: 8 });
List({ space: 12, initialIndex: 0 }) {
ForEach(this.arr, (item: number) => {
ListItem() {
Text('' + item)
.width('90%')
.height(72)
.backgroundColor('#FFFFFF')
.borderRadius(24)
.fontSize(16)
.fontWeight(500)
.textAlign(TextAlign.Center);
}
.onClick(() =>
this.naviStack.pushPath({ name: 'ContentPage' }));
}, (item: number) => item.toString());
}
.scrollBar(BarState.Off)
.height('100%')
.width('100%')
.margin({
top: 12,
left: '10%'
});
}
.width('100%')
.height('100%');
}
.width('100%')
.height('100%');
}
.mode(NavigationMode.Auto)
// 模式切换时,更新 mode 变量和路由栈
.onNavigationModeChange(mode => {
this.naviStack.mode = mode;
if (mode === NavigationMode.Split) {
if (this.naviStack.size() === 0) {
this.naviStack.pushPath({ name: 'EmptyPage' });
}
} else {
this.naviStack.removeByName('EmptyPage');
}
})
.title('首页')
.hideTitleBar(true)
.hideToolBar(true);
}.width('100%').height('100%').backgroundColor('#F1F3F5');
}
}
EmptyPage.ets 空内容占位子页面
[@Builder](/user/Builder)
export function EmptyPageBuilder() {
EmptyPage()
}
[@Component](/user/Component)
struct EmptyPage {
[@State](/user/State) message: string = 'Empty Page';
pathStack: NavPathStack = new NavPathStack()
build() {
NavDestination() {
RelativeContainer() {
Text(this.message)
.id('EmptyPage')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
});
}
.height('100%')
.width('100%');
}
.onReady((context: NavDestinationContext) => {
this.pathStack = context.pathStack
})
}
}
ContentPage.ets 内容占位子页面
import { DerivedNavPathStack } from './NavigationExample';
[@Builder](/user/Builder)
export function ContentPageBuilder() {
ContentPage();
}
[@Component](/user/Component)
struct ContentPage {
[@State](/user/State) message: string = 'Content Page';
pathStack: DerivedNavPathStack = new DerivedNavPathStack();
build() {
NavDestination() {
RelativeContainer() {
Text(this.message)
.id('ContentPage')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
});
}
.height('100%')
.width('100%');
}
.onReady((context: NavDestinationContext) => {
this.pathStack = context.pathStack as DerivedNavPathStack;
})
// 设置返回事件回调
.onBackPressed(() => this.pathStack.customBack());
}
}
route_map.json 系统路由表
{
"routerMap": [
{
"name": "EmptyPage",
"pageSourceFile": "src/main/ets/pages/EmptyPage.ets",
"buildFunction": "EmptyPageBuilder"
},
{
"name": "ContentPage",
"pageSourceFile": "src/main/ets/pages/ContentPage.ets",
"buildFunction": "ContentPageBuilder"
}
]
}
在HarmonyOS鸿蒙Next中,使用Navigation组件进行分栏模式开发时,若需设置右侧的默认显示内容,可通过以下方式实现:
-
利用Navigation的回调:
- 监听Navigation的显示模式变化,当进入分栏模式(Split)时,通过
this.naviStack.pushPath()
或this.naviStack.pushPathByName()
方法设置右侧默认页面。 - 可以在
aboutToAppear()
方法或监听NavigationMode
变化的回调中实现此逻辑。
- 监听Navigation的显示模式变化,当进入分栏模式(Split)时,通过
-
确保逻辑在双栏模式被识别时执行:
- 通过判断
NavigationMode
是否为Split
,来确保上述设置默认页面的逻辑只在双栏模式下执行。
- 通过判断
-
路由配置:
- 确保已正确配置路由,且目标页面已正确注册在路由表中。
-
注意事项:
- 在设置默认页面时,确保页面名称和参数正确无误。
- 若需传递参数至默认页面,可在
pushPath()
或pushPathByName()
方法中指定。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html 。