轻松上手-Navigation路由 H5 原创

狼哥Army
发布于 2024-10-18 10:39
浏览
0收藏
作者:狼哥
团队:坚果派
团队介绍:坚果派由坚果等人创建,团队拥有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页面中享受丰富的网页内容,并通过点击跳转到鸿蒙应用内的路由页面,实现无缝的跨平台体验。

效果预览

轻松上手-Navigation路由 H5-鸿蒙开发者社区 轻松上手-Navigation路由 H5-鸿蒙开发者社区
轻松上手-Navigation路由 H5-鸿蒙开发者社区 轻松上手-Navigation路由 H5-鸿蒙开发者社区
轻松上手-Navigation路由 H5-鸿蒙开发者社区 轻松上手-Navigation路由 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及以上。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2024-10-18 10:58:23修改
收藏
回复
举报
回复
    相关推荐