轻松上手-Navigation路由 H5 原创
作者:狼哥
团队:坚果派
团队介绍:坚果派由坚果等人创建,团队拥有12个华为HDE带领热爱HarmonyOS/OpenHarmony的开发者,以及若干其他领域的三十余位万粉博主运营。专注于分享HarmonyOS/OpenHarmony、ArkUI-X、元服务、仓颉。团队成员聚集在北京,上海,南京,深圳,广州,宁夏等地,目前已开发鸿蒙原生应用,三方库60+,欢迎交流。
介绍
HarmonyOS的Navigation组件是ArkUI中用于管理页面路由的容器组件,它支持模块内和跨模块的路由切换,提供自然流畅的转场体验及多种标题栏样式,适用于一次开发、多端部署的场景。通过Navigation组件,开发者可以轻松定义页面路径并实现页面间的跳转,同时在不同设备上自动适配显示大小,提升用户体验。
对于Web组件H5页面的显示,HarmonyOS提供了与Web技术融合的能力,使得H5页面可以在鸿蒙设备上流畅运行。当用户点击H5页面中的特定元素时,可以通过集成的小程序路由或JavaScript桥接技术,实现向鸿蒙应用内路由页面的跳转。
HarmonyOS的Navigation组件与Web组件H5页面显示技术相结合,不仅丰富了应用的页面交互方式,还提升了应用间的互操作性。用户可以在H5页面中享受丰富的网页内容,并通过点击跳转到鸿蒙应用内的路由页面,实现无缝的跨平台体验。
效果预览
知识点
1. Navigation组件
2. 使用Web组件加载页面
3. 前端页面调用应用侧函数
4. Emitter线程间通信
工程目录
├──entry/src/main/ets // 代码区
│ ├──entryability
│ │ └──EntryAbility.ets
│ ├──model
│ │ └──ParamClass.ets // 参数Class
│ ├──pages
│ │ └──Index.ets // 首页
│ └──view
│ ├──FromArkTSDetailPage.ets // ArkTS详情页
│ └──FromArkTSOnePage.ets // ArkTS简单页
│ └──FromWebHtmlPage.ets // Web组件H5页面
└──entry/src/main/resources // 应用资源目录
└──rawfile
└──index.html // 本地H5页面
具体实现
首页显示页面间跳转流程和一个跳转到第一个ArkTS页面按钮,点击首页跳转按钮跳转到普通ArkTS页面,在普通ArkTS页面点击跳转到有Web组件的H5页面,在Web组件H5页面,点击H5页面里的图片,跳转到详情页面,详情页面显示从H5页面传出的参数,并显示传出参数的图片,如果点击Web组件H5页面按钮,跳转到详情页,由于没有点击H5页面,参数为默认图片值。
1. ParamClass实体类
ParamClass包含img属性图片名称,size属性图片大小,无参构造函数,callArkTS提供给H5调用的函数。
import { emitter } from '@kit.BasicServicesKit';
export class ParamClass {
// 图片名称
img?: string;
// 图片大小
size?: number;
// 无参构造函数
constructor() {
}
// 提供H5调用函数
callArkTS(params: ESObject) {
// emitter线程通信参数
let eventData: emitter.EventData = {
data: params
};
// 发送事件
emitter.emit({eventId: 11}, eventData)
}
}
2. HTML文件
本地html文件,主要是显示三张图片,点击图片调用函数,函数里调用应用侧函数,paramClass是在Web组件里javaScriptProxy定义name, paramClass.callArkTS这里的callArkTS是javaScriptProxy里methodList定义的。
<!DOCTYPE html>
<html>
<body>
<img src="seven_one.jpg" width="512", height="300" onclick="callArkTS('seven_one.jpg')">
<img src="seven_two.jpg" width="512", height="300" onclick="callArkTS('seven_two.jpg')">
<img src="seven_three.jpg" width="512", height="300" onclick="callArkTS('seven_three.jpg')">
<script>
function callArkTS(imgId) {
let obj = {
'img': imgId,
'size': 3
}
paramClass.callArkTS(obj);
}
</script>
</body>
</html>
3. 首页
首页使用了Navigation组件,初始化路由栈,操作流程说明和跳转按钮。
@Entry
@Component
struct Index {
// 页面路由栈
@Provide('navPathStack') navPathStack: NavPathStack = new NavPathStack();
// 跳转页面入口
@Builder
nimblePageRouter(name: string, param?: object) {
if (name === 'fromArkTSOnePage') {
FromArkTSOnePage()
}else if (name === 'fromWebHtmlPage') {
FromWebHtmlPage()
}else if (name === 'fromArkTSDetailPage') {
FromArkTSDetailPage()
}
}
build() {
Navigation(this.navPathStack) {
页面布局参看下面......
}
.hideTitleBar(false)
.title('首页')
.navDestination(this.nimblePageRouter)
}
}
Column({ space: 20 }) {
Text('1. 点击按钮跳转到ArkTS第一页面')
.fontSize(18)
.fontWeight(600)
.fontColor(Color.Red)
.width('100%')
Text('2. 点击按钮跳转到Web组件H5页面')
.fontSize(14)
.width('100%')
Text('3. 点击按钮跳转到ArkTS详情页面')
.fontSize(14)
.width('100%')
Text('4. 点击按钮跳转到首页页面')
.fontSize(14)
.width('100%')
Button('跳转ArkTS第一页面')
.width('80%')
.height(40)
.onClick(() => {
// 跳转页面
let pathInfo : NavPathInfo = new NavPathInfo('fromArkTSOnePage', null)
this.navPathStack.pushDestination(pathInfo, true);
})
}
.width('100%')
.height('100%')
.padding(20)
4. 普通ArkTS页面
此页面主要使用NavDestination显示页面内容。
@Component
export struct FromArkTSOnePage {
@Consume('navPathStack') navPathStack: NavPathStack;
build() {
NavDestination() {
Column({ space: 20 }) {
Text('1. 点击按钮跳转到ArkTS第一页面')
.fontSize(14)
.width('100%')
Text('2. 点击按钮跳转到Web组件H5页面')
.fontSize(18)
.fontWeight(600)
.fontColor(Color.Red)
.width('100%')
Text('3. 点击按钮跳转到ArkTS详情页面')
.fontSize(14)
.width('100%')
Text('4. 点击按钮跳转到首页页面')
.fontSize(14)
.width('100%')
Button('跳到H5页面')
.width('80%')
.height(40)
.onClick(() => {
let pathInfo : NavPathInfo = new NavPathInfo('fromWebHtmlPage', null)
this.navPathStack.pushDestination(pathInfo, true);
})
}
.width('100%')
.height('100%')
.padding(20)
}
.title('ArkTS第一个页面')
}
}
5. Web组件H5页面
此页面主要使用Web组件显示本地H5页面,并且订阅了eventId为11的事件。
@Component
export struct FromWebHtmlPage {
@Consume('navPathStack') navPathStack: NavPathStack;
webviewController: webview.WebviewController = new webview.WebviewController();
// 声明需要注册的对象
private paramClass: ParamClass = new ParamClass();
aboutToAppear(): void {
// 订阅eventId为11的事件
emitter.on({eventId: 11}, (result) => {
console.info('xxx ArkTS Hello World!'+JSON.stringify(result.data));
let pathInfo : NavPathInfo = new NavPathInfo('fromArkTSDetailPage', result.data)
this.navPathStack.pushDestination(pathInfo, true);
})
}
build() {
NavDestination() {
Column({ space: 20 }) {
... 部分代码下面
// Web组件加载本地index.html页面
Web({ src: $rawfile('index.html'), controller: this.webviewController})
// 将对象注入到web端
.javaScriptProxy({
object: this.paramClass,
name: "paramClass",
methodList: ["callArkTS"],
controller: this.webviewController
})
.width('100%')
.backgroundColor('#CCC')
}
.width('100%')
.height('100%')
.padding(20)
}
.title('Web组件H5页面')
}
}
Text('1. 点击按钮跳转到ArkTS第一页面')
.fontSize(14)
.width('100%')
Text('2. 点击按钮跳转到Web组件H5页面')
.fontSize(14)
.width('100%')
Text('3. 点击按钮跳转到ArkTS详情页面')
.fontSize(18)
.fontWeight(600)
.fontColor(Color.Red)
.width('100%')
Text('4. 点击按钮跳转到首页页面')
.fontSize(14)
.width('100%')
Button('跳到详情页面')
.width('80%')
.height(40)
.onClick(() => {
let pathInfo : NavPathInfo = new NavPathInfo('fromArkTSDetailPage', null)
this.navPathStack.pushDestination(pathInfo, true);
})
Text('以下图片来自H5页面')
.fontSize(14)
.fontColor(Color.Orange)
.width('100%')
6. 详情页面
此页面主要在NavDestination调用onReady回调函数接收参数,然后展示传过来的图片。
@Component
export struct FromArkTSDetailPage {
@Consume('navPathStack') navPathStack: NavPathStack;
@State imgId: string = 'seven_blank.jpg'
build() {
NavDestination() {
Column({ space: 20 }) {
...
Image($rawfile(this.imgId))
.width('100%')
}
.width('100%')
.height('100%')
.padding(20)
}
.title('ArkTS详情页面')
.onReady((cxt) => {
if (cxt.pathInfo.param) {
let obj = cxt.pathInfo.param as ParamClass;
if (obj.img) {
console.info('xx', `获取图片路径: ${obj.img}`)
this.imgId = obj.img
}
}
})
}
}
总结
通过此案例,可以学习到Navigation组件路由导航使用,H5前端页面调用应用侧函数,还有就是Emitter主要提供线程间发送和处理事件的能力,包括对持续订阅事件或单次订阅事件的处理、取消订阅事件、发送事件到事件队列等。
约束与限制
1.本示例仅支持标准系统上运行,支持设备:华为手机。
2.HarmonyOS系统:HarmonyOS NEXT Developer Beta1及以上。
3.DevEco Studio版本:DevEco Studio NEXT Developer Beta1及以上。
4.HarmonyOS SDK版本:HarmonyOS NEXT Developer Beta1 SDK及以上。