HarmonyOS鸿蒙Next中Navigation实现类似闪屏的效果
HarmonyOS鸿蒙Next中Navigation实现类似闪屏的效果 使用navigation组件实现类似闪屏的效果,需要把home页面替换掉,但是使用replacePathByName方法无法彻底将home页面替换,点击返回按钮还是会回到home页面,看到相关帖子说navigation栈底元素无法被移除,请问是否有官网的文档说明navigation栈底元素无法被移除
更多关于HarmonyOS鸿蒙Next中Navigation实现类似闪屏的效果的实战教程也可以访问 https://www.itying.com/category-93-b0.html
【解决方案】
完整的Navigation实现闪屏页方式可以参考demo:Navigation实现闪屏页。
- 方案一:通过隐藏导航页和重写返回键的方法,实现不返回开屏页。
- 开屏页通过导航页Navigation容器组件实现;
- Navigation启动时,通过this.pathStack.pushPathByName直接跳转到MainPage界面;
- 添加路由拦截,当路由目标页面名称为navBar(Navigation首页名字)时,就跳转到MainPage界面;
- 设置Navigation属性hideNavBar为true,隐藏返回导航页。
示例代码如下:
// MainPage.ets
@Component
struct MainPage {
pageName: string = '';
pathStack: NavPathStack | undefined = undefined;
build() {
NavDestination() {
Column() {
Text('this is MainPage').fontSize(24)
Button(`push Page`).width('80%').margin({ top: 10, bottom: 10 })
.onClick(() => {
this.pathStack?.pushPathByName('Page', '');
})
Button(`pop`).width('80%').margin({ top: 10, bottom: 10 })
.onClick(() => {
this.pathStack?.pop();
})
}
}.title('MainPage')
.onReady((context: NavDestinationContext) => {
this.pageName = context.pathInfo.name;
this.pathStack = context.pathStack;
})
}
}
// Page.ets
@Component
struct Page {
pageName: string = '';
pathStack: NavPathStack | undefined = undefined;
build() {
NavDestination() {
Column() {
Text('this is Page').fontSize(24)
Button(`pop`).width('80%').margin({ top: 10, bottom: 10 })
.onClick(() => {
this.pathStack?.pop();
})
}
}.title('Page')
.onReady((context: NavDestinationContext) => {
this.pageName = context.pathInfo.name;
this.pathStack = context.pathStack;
})
}
}
// Index.ets(即启动页)
import { promptAction } from '@kit.ArkUI';
@Entry
@Component
struct Index {
pathStack: NavPathStack = new NavPathStack();
@State hideNavBar: boolean = false
aboutToAppear(): void {
setTimeout(() => {
this.pathStack.pushPathByName('MainPage', undefined, false);
this.hideNavBar = true
// 添加路由拦截功能
this.pathStack.setInterception({
willShow: (from: NavDestinationContext | NavBar, to: NavDestinationContext | NavBar,
operation: NavigationOperation, isAnimated: boolean) => {
// 如果返回到首页,就跳转为MainPage页面
if (to == 'navBar') {
promptAction.showToast({ message: '无法返回到首页' })
this.pathStack.pushPathByName('MainPage', undefined, false);
}
}
})
}, 2000)
}
@Builder
pagesMap(name: string, param: number) {
if (name == 'MainPage') {
MainPage()
} else if (name == 'Page') {
Page()
}
}
build() {
Navigation(this.pathStack) {
Text('欢迎进入APP').fontSize(30)
}.title('启动页')
.hideNavBar(this.hideNavBar)
.navDestination(this.pagesMap)
}
}
- 方案二:通过销毁作为开屏页的NavDestination页面,实现不返回开屏页。
- 首页使用Navigation作为根容器,闪屏页使用NavDestination作为根容器;
- 在首页的aboutToAppear回调中跳转到闪屏页;
- 闪屏页在定时器setTimeout回调中通过removeByName销毁自身。
示例代码如下:
// Index.ets
@Entry
@Component
struct Index {
@Provide('navPathStack') navPathStack: NavPathStack = new NavPathStack();
@Builder
pageMap(name: string) {
if (name === "Splash") {
Splash()
}
}
aboutToAppear(): void {
this.navPathStack.pushPathByName("Splash", "")
}
build() {
Navigation(this.navPathStack) {
Column() {
Text('首页')
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
.hideToolBar(true)
.navDestination(this.pageMap)
}
}
// Splash.ets
@Component
export struct Splash {
@Consume('navPathStack') navPathStack: NavPathStack;
aboutToAppear(): void {
setTimeout(() => {
this.navPathStack.removeByName("Splash")
}, 2000)
}
build() {
NavDestination() {
Column() {
Text('闪屏页')
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
.hideTitleBar(true)
}
}
【背景知识】
- Navigation组件是路由导航的根视图容器,一般作为Page页面的根容器使用。其主要用于实现页面间以及组件内部的页面跳转。removeByName方法可以将指定的NavDestination页面删除。
- NavDestination是Navigation的子页面的根容器,onBackPressed方法可以重写返回键逻辑。
更多关于HarmonyOS鸿蒙Next中Navigation实现类似闪屏的效果的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
// 在闪屏页销毁时重建根容器
import { NavPathStack } from '@kit.ArkUI';
@Component
struct SplashPage {
@Provide('navStack') navStack: NavPathStack = new NavPathStack();
aboutToDisappear() {
this.navStack.popAll();
this.navStack.pushPathByName('MainPage');
}
}
HarmonyOS的社区里有很多技术大牛分享经验,学到了很多有用的知识。
可以使用一个状态变量控制,如果想着全局控制这个 isShowHome, 可以把它放到 AppStorage 里面
@State isShowHome: boolean = true
Navigation(){
if (this.isShowHome) {
PageHome()
} else {
PageOther()
}
}
在HarmonyOS Next中,可通过Navigation组件结合页面导航与动画实现类似闪屏效果。使用Navigation的页面栈管理能力,在应用启动时加载初始页面作为闪屏页,并利用Navigation的过渡动画或自定义动画效果(如淡入淡出)展示短暂界面。随后通过路由跳转快速切换至主页面。关键步骤包括:在EntryAbility中配置初始路由为闪屏页,在闪屏页使用定时器或异步任务延迟后调用router.pushUrl跳转。全程基于ArkTS声明式开发,无需依赖Java或C。
在HarmonyOS Next中,Navigation组件的栈底页面(即初始页面)确实无法通过replacePathByName
方法移除。这是Navigation组件的设计机制,目的是确保应用始终有一个可用的根页面,避免出现空栈状态导致应用无响应或意外退出。
根据官方设计规范,栈底页面作为Navigation容器的基础,不允许被完全替换或移除。当你使用replacePathByName
替换栈底页面时,实际上是在栈底之上覆盖新页面,但原始栈底页面仍保留在导航栈中。因此点击返回按钮时,会回到初始的home页面。
要实现类似闪屏效果并彻底替换home页面,建议采用以下方案:
- 将闪屏页面设计为应用的初始页面(即Navigation的根页面)
- 在闪屏页面完成展示后,使用
router.clear
清空整个导航栈 - 立即使用
router.replaceUrl
跳转到真正的home页面
这种方法可以确保闪屏页面不会留在导航栈中,用户点击返回时将直接退出应用,符合闪屏页面的典型交互逻辑。
关于栈底页面不可移除的具体说明,可参考官方Navigation组件文档中"页面栈管理"章节的相关约束说明。