HarmonyOS鸿蒙Next中nav tab下的功能点击跳转到了a 但是a不想返回到tab下 需要怎么做
HarmonyOS鸿蒙Next中nav tab下的功能点击跳转到了a 但是a不想返回到tab下 需要怎么做 为什么当前路由栈只有一个 还能返回
【背景知识】
onBackPressed:当与Navigation绑定的页面栈中存在内容时,此回调生效。当点击返回键时,触发该回调。返回值为true时,表示重写返回键逻辑,返回值为false时,表示回退到上一个页面。
setInterception:设置Navigation页面跳转拦截回调。
【解决方案】
方案一:通过NavDestination组件的onBackPressed回调对返回事件进行拦截,该方案支持拦截系统侧滑返回事件和使用NavDestination的标题栏返回键返回事件,不支持拦截使用NavPathStack.pop()返回。
示例代码如下:
import { promptAction, ShowDialogSuccessResponse } from '@kit.ArkUI';
@Entry
@Component
struct SideslipIntercept {
controller: TextAreaController = new TextAreaController();
@State text: string = '';
@Provide pageStackForComponentSharedPages: NavPathStack = new NavPathStack();
build() {
// 应用主页用NavDestination承载,用于显示Navigation的内容区
Navigation(this.pageStackForComponentSharedPages) {
}
.onAppear(() => {
this.pageStackForComponentSharedPages.pushPathByName('MainPage', null, false);
})
// 创建NavDestination组件,需使用此组件的onBackPressed回调拦截返回事件
.navDestination(this.textArea)
}
@Builder
textArea(name: string) {
NavDestination() {
Column() {
TextArea({
text: this.text,
placeholder: 'input your word...',
controller: this.controller
})
.onChange((value: string) => {
this.text = value;
})
}
.justifyContent(FlexAlign.Start)
.width('100%')
.height('100%')
}
.onBackPressed(() => {
// 此处可添加拦截处理逻辑,然后return true放行
promptAction.showDialog({
message: '是否返回',
alignment: DialogAlignment.Center,
buttons: [
{
text: '取消',
color: '#0000FF'
},
{
text: '确认',
color: '#0000FF'
}
]
}).then((data: ShowDialogSuccessResponse) => {
// 操作菜单的响应结果,选中按钮在buttons数组中的索引,从0开始,第二个索引为1
// 点击取消按钮,留在此页面
if (data.index === 0) {
console.info('取消')
}
// 点击确认按钮,返回上层页面
if (data.index === 1) {
this.pageStackForComponentSharedPages.pop()
console.info('确认')
}
})
return true;
})
}
}
方案二:使用setInterception拦截Navigation页面跳转。
示例代码如下:
// Index.ets
import { promptAction, ShowDialogSuccessResponse } from '@kit.ArkUI';
@Entry
@Component
struct NavigationExample {
pageInfos: NavPathStack = new NavPathStack();
isUseInterception: boolean = false;
isConfirm: boolean = false;
registerInterception() {
this.pageInfos.setInterception({
// 页面跳转前拦截,允许操作栈,在当前跳转中生效。
willShow: async (from: NavDestinationContext | "navBar", to: NavDestinationContext | "navBar",
operation: NavigationOperation, animated: boolean) => {
if (!this.isUseInterception) {
return;
}
if (typeof from === "string") {
return;
}
let origin: NavDestinationContext = from as NavDestinationContext;
let pathName = origin.pathInfo.name;
if (operation === NavigationOperation.POP && !this.isConfirm) {
promptAction.showDialog({
message: '是否返回',
alignment: DialogAlignment.Center,
buttons: [
{
text: '取消',
color: '#0000FF'
},
{
text: '确认',
color: '#0000FF'
}
]
}).then((data: ShowDialogSuccessResponse) => {
// 操作菜单的响应结果,选中按钮在buttons数组中的索引,从0开始,第二个索引为1
// 点击取消按钮,留在此页面
if (data.index === 0) {
console.info('取消')
}
// 点击确认按钮,返回上层页面
if (data.index === 1) {
this.isConfirm = true; // 用户判断是否确认返回上层页面的标识
origin.pathStack.pop();
console.info('确认')
}
})
origin.pathStack.pop(); // 弹窗未响应前,停留在当前页面
origin.pathStack.pushPathByName(pathName, null, false);
} else {
this.isConfirm = false;
}
},
// 页面跳转后回调,在该回调中操作栈在下一次跳转中刷新。
didShow: (from: NavDestinationContext | "navBar", to: NavDestinationContext | "navBar",
operation: NavigationOperation, isAnimated: boolean) => {
if (!this.isUseInterception) {
return;
}
if (typeof from === "string") {
console.info("current transition is from navigation home");
} else {
console.info(`current transition is from ${(from as NavDestinationContext).pathInfo.name}`);
}
if (typeof to === "string") {
console.info("current transition to is navBar");
} else {
console.info(`current transition is to ${(to as NavDestinationContext).pathInfo.name}`);
}
},
// Navigation单双栏显示状态发生变更时触发该回调。
modeChange: (mode: NavigationMode) => {
if (!this.isUseInterception) {
return;
}
console.info(`current navigation mode is ${mode}`);
}
})
}
build() {
Navigation(this.pageInfos) {
Column() {
Button('pushPath', { stateEffect: true, type: ButtonType.Capsule })
.width('80%')
.height(40)
.margin(20)
.onClick(() => {
this.pageInfos.pushPath({ name: 'pageOne' }); // 将name指定的NavDestination页面信息入栈
})
// 需要先点击此按钮,然后再点击pushPath按钮
Button('use interception', { stateEffect: true, type: ButtonType.Capsule })
.width('80%')
.height(40)
.margin(20)
.onClick(() => {
this.isUseInterception = !this.isUseInterception;
if (this.isUseInterception) {
this.registerInterception();
} else {
this.pageInfos.setInterception(undefined);
}
})
}
}.title('NavIndex')
}
}
// PageOne.ets
class TmpClass {
count: number = 10;
}
@Builder
export function PageOneBuilder(name: string, param: Object) {
PageOne()
}
@Component
export struct PageOne {
pageInfos: NavPathStack = new NavPathStack();
build() {
NavDestination() {
Column() {
Button('pageOne', { stateEffect: true, type: ButtonType.Capsule })
.width('80%')
.height(40)
.margin(20)
}.width('100%').height('100%')
}.title('pageOne')
}
}
更多关于HarmonyOS鸿蒙Next中nav tab下的功能点击跳转到了a 但是a不想返回到tab下 需要怎么做的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
可以拦截 a 页面的返回事件:
无论是手势返回,还是左上角按钮返回都会调用: onBackPressed 方法,返回true, 表示自己处理返回事件。
// a page
NavDestination() {
Column() {}
}
.onBackPressed(() => {
// 处理返回事件
return true
})
在HarmonyOS Next中,使用router.clear()
清除路由栈后再跳转。具体代码:
import router from '@ohos.router'
// 在页面A执行跳转时
router.clear()
router.pushUrl({
url: 'pages/TargetPage'
})
这会清空导航历史,使目标页面成为新栈底。或者使用router.replaceUrl()
替换当前页面:
router.replaceUrl({
url: 'pages/TargetPage'
})
在HarmonyOS Next中,要实现从nav tab跳转到页面A后不返回到tab页,可以通过以下方式处理:
- 使用router.replace()替代router.push()方法跳转,这样会替换当前路由而不是压栈:
router.replace({
url: 'pages/A'
})
- 如果需要更精细的控制,可以在页面A的onBackPress()回调中拦截返回事件:
onBackPress() {
// 直接返回true阻止默认返回行为
return true
}
- 关于路由栈问题:即使只有一个页面,系统仍会保留默认的返回逻辑。要完全清除历史记录,可以使用:
router.clear()
这些方法可以避免从页面A返回到tab页的情况。根据具体场景选择最适合的方案即可。