简介
在应用开发中存在大量应用内多页面跳转场景,使用Navigation
导航组件做统一的页面跳转管理,Navigation
组件提供一系列属性方法来设置页面的标题栏、工具栏以及菜单栏的展示样式。还支持动态加载,navPathStack路由跳转等能力。
本文就以Navigation页面切换为例,展开讲解Navigation以上的技术点,帮助开发者快速学习。
场景概述
导航组件Navigation
一般作为Page页面的根容器,Navigation组件可以作为首页和内容页的容器。首页显示Navigation的子组件,内容页显示NavDestination的子组件,主页和内容页通过路由进行切换。
Navigation的路由切换的方式有两种:
- 在API Version 9上,首页导航内容需要配合NavRouter组件实现页面路由。
- 从API Version 10开始,首页推荐使用NavPathStack配合NavDestination属性进行页面路由。
本次示例主要介绍NavPathStack的使用。
导航组件Navigation还可以通过mode属性实现多设备适配,具体请参考MULTIDEVICE_ADAPTATION.md
通过本篇文章的学习,你将学会:
1.如何使用NavPathStack路由转场
2.如何在Navigation中跨包引用hsp
3.如何在Navigation中使用动态加载
Router与Navigation适用场景对比
组件 | 适用场景 | 特点 | 转场动画效果对比 |
---|---|---|---|
Router | 模块间与模块内页面切换 | 通过每个页面的url实现模块间解耦 | 页面平推转场效果 |
Navigation | 模块内页面切换 | 通过组件级路由统一路由管理 | 向右折叠转场效果 |
使用NavPathStack路由转场
-
NavPathStack有两种路由切换方法,一种是pushPath,如首页---->设置页面,通过使用this.pageStack.pushPath({ name: url })进行跳转;另外一种是pushPathByName,如首页---->详情页面,通过使用this.pageStack.pushPathByName(name, item)进行跳转,其中item为需要传递的参数。
-
NavPathStack支持pop、move、clear方法的使用;pop方法的作用是弹出路由栈栈顶元素,如首页进入商品详情页面,在详情页面使用this.pageStack.pop()方法返回到首页,clear方法的作用是清除栈中所有页面, 如首页跳转到详情页面,详情页面再进入直播页面,在直播页面通过使用this.pageStack.clear()直接返回到首页。除此之外,还有popTo(回退路由栈到第一个名为name的NavDestination页面)、 popToIndex(回退路由栈到index指定的NavDestination页面)、moveToTop(将第一个名为name的NavDestination页面移到栈顶)、moveIndexToTop(将index指定的NavDestination页面移到栈顶)方法, 由于本示例暂时没有合适的按钮去承载这些功能,所以本示例未体现。
-
路由栈信息,如下所示:
获取栈中所有NavDestination页面的名称:this.pageInfos.getAllPathName() 获取index指定的NavDestination页面的参数信息:this.pageInfos.getParamByIndex(1) 获取全部名为name的NavDestination页面的参数信息:this.pageInfos.getParamByName('pageTwo') 获取全部名为name的NavDestination页面的位置索引:this.pageInfos.getIndexByName('pageOne') 获取栈大小:this.pageInfos.size()
实现思路
以Navigation组件为基础,通过路由管理实现页面之间的跳转。
开发步骤
Navigation中使用路由跳转页面
-
在onClick事件中,调用路由管理中的push方法。源码参考FunctionalScenes.ets
Column() .onClick(() => { DynamicsRouter.push(listData.routerInfo, listData.param); })
-
在DynamicsRouter的push方法中,通过NavPathStack.pushPath方法实现页面的跳转。源码参考DynamicsRouter
public static async push(routerInfo: RouterInfo, param?: string): Promise<void> { const pageName: string = routerInfo.pageName; const moduleName: string = routerInfo.moduleName; ... if (isImportSucceed) { const builderName: string = moduleName + "/" + pageName; DynamicsRouter.getNavPathStack().pushPath({ name: builderName, param: param }); } }
新模块中配置路由管理
-
添加需要加载的子模块的依赖,详细代码请参考oh-package.json。
"dependencies": { "@ohos/event-propagation": "file:../../feature/eventpropagation", ... }
-
添加动态import变量表达式需要的参数,此处在packages中配置的模块名必须和oh-package.json中配置的名称相同,详细代码请参考build-profile.json5。
... "buildOption": { "arkOptions": { "runtimeOnly": { "packages": [ "@ohos/event-propagation", ... ] } } }
-
在routermodule模块中添加需要跳转的moduleName(模块名)和pageName(页面名),RouterInfo中配置的moduleName必须和oh-package.json中配置的名称相同,RouterInfo中添加的pageName是子模块中需要加载的页面,详细代码请参考RouterInfo.ets。
export class RouterInfo { moduleName: string = ''; pageName: string = ''; constructor(moduleName: string, pageName: string) { this.moduleName = moduleName; this.pageName = pageName; } ... static readonly EVENT_TRANSMISSION_SOLUTION: RouterInfo = new RouterInfo('@ohos/event-propagation', 'EventPropagation'); ... }
-
在WaterFlowData.ets中,将子模块要加载的页面,添加到列表中,详细代码请参考WaterFlowData.ets。
export const waterFlowData: SceneModuleInfo[] = [ ... new SceneModuleInfo($r("app.media.event_propagation"), '阻塞事件冒泡', RouterInfo.EVENT_TRANSMISSION_SOLUTION, '其他', 1), ... }
-
在子模块中添加路由管理的依赖,详细代码可参考oh-package.json。
... "dependencies": { ... "@ohos/dynamicsrouter": "file:../../common/routermodule" }
-
在子模块中添加动态加载页面组件的接口harInit,其中pageName和RouterInfo中配置的pageName相同,import()接口中传入的参数,是页面的相对路径。详细代码可参考Index.ets。 如果模块中有多个页面需要跳转,则需要配置多个pageName和页面路径,并且pageName和页面路径需要一一对应,否则无法跳转到预期中的页面,详细代码可参考barchart模块中的Index.ets。
export function harInit(pageName: string) { switch (pageName) { case RouterInfo.EVENT_TRANSMISSION_SOLUTION.pageName: import('./src/main/ets/view/EventPropagation'); break; } }
-
在子模块中添加动态创建组件的方法,并注册到路由管理中,详细代码可参考EventPropagation.ets。
... @Builder export function getEventPropagation(): void { EventPropagation(); } DynamicsRouter.registerRouterPage(RouterInfo.EVENT_TRANSMISSION_SOLUTION,wrapBuilder(getEventPropagation));
最后
小编在之前的鸿蒙系统扫盲中,有很多朋友给我留言,不同的角度的问了一些问题,我明显感觉到一点,那就是许多人参与鸿蒙开发,但是又不知道从哪里下手,因为资料太多,太杂,无从选择。有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)文档用来跟着学习是非常有必要的。
为了确保高效学习,建议规划清晰的学习路线
GitCode - 全球开发者的开源社区,开源代码托管平台希望这一份鸿蒙学习文档能够给大家带来帮助~
鸿蒙(HarmonyOS NEXT)最新学习路线
该路线图包含基础技能、就业必备技能、多媒体技术、六大电商APP、进阶高级技能、实战就业级设备开发,不仅补充了华为官网未涉及的解决方案
路线图适合人群:
IT开发人员:想要拓展职业边界
零基础小白:鸿蒙爱好者,希望从0到1学习,增加一项技能。
技术提升/进阶跳槽:发展瓶颈期,提升职场竞争力,快速掌握鸿蒙技术
2.学习视频+学习PDF文档
HarmonyOS Next 最新全套视频教程 (鸿蒙语法ArkTS、TypeScript、ArkUI教程……)
纯血版鸿蒙全套学习文档(面试、文档、全套视频等)
鸿蒙APP开发必备
总结
总的来说,华为鸿蒙不再兼容安卓,对程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,才能在这个变革的时代中立于不败之地。