HarmonyOS NEXT应用开发之ArkWeb同层渲染

介绍

该方案展示了ArkWeb同层渲染:将系统原生组件直接渲染到前端H5页面上,原生组件不仅可以提供H5组件无法实现的一些功能,还能提升用户体验的流畅度

效果图预览

使用说明

  1. 进入页面即可看到同层渲染效果,Text,search,image都是原生组件。

实现思路

  1. 添加权限。
"ohos.permission.INTERNET"
  1. 创建控制器管理绑定的NodeContainer组件。
class SearchNodeController extends NodeController {private rootNode: BuilderNode<[Params]> | undefined | null = null;private embedId : string = "";private surfaceId : string = "";private renderType :NodeRenderType = NodeRenderType.RENDER_componentTypeDISPLAY;private componentWidth : number = 0;private componentHeight : number = 0;private componentType : string = "";setRenderOption(params : NodeControllerParams): void {this.surfaceId = params.surfaceId;this.renderType = params.renderType;this.embedId = params.embedId;this.componentWidth = params.width;this.componentHeight = params.height;this.componentType = params.type;}/*** 在对应NodeContainer创建的时候调用、或者通过rebuild方法调用刷新*/makeNode(uiContext: UIContext): FrameNode | null{this.rootNode = new BuilderNode(uiContext, { surfaceId: this.surfaceId, type: this.renderType});if (this.componentType === 'native/component') {this.rootNode.build(wrapBuilder(searchBuilder), { width : this.componentWidth, height : this.componentHeight});} else {}// 返回FrameNode节点return this.rootNode.getFrameNode();}/*** 设置BuilderNode节点*/setBuilderNode(rootNode: BuilderNode<Params[]> | null): void{this.rootNode = rootNode;}/*** 获取BuilderNode节点*/getBuilderNode(): BuilderNode<[Params]> | undefined | null{return this.rootNode;}/*** 更新BuilderNode节点*/updateNode(arg: Object): void {this.rootNode?.update(arg);}/*** 获取EmbedId*/getEmbedId() : string {return this.embedId;}/*** 将触摸事件派发到rootNode创建出的FrameNode上*/postEvent(event: TouchEvent | undefined) : boolean {return this.rootNode?.postTouchEvent(event) as boolean;}
}
  1. 添加同层渲染的组件。
@Component
struct SearchComponent {
@Prop params: Params;
controller: SearchController = new SearchController();build() {Column() {Column({ space: MARGIN_VERTICAL }) {Text($r('app.string.headline')).fontSize($r('app.string.ohos_id_text_size_body1'))Text($r('app.string.illustrate')).fontSize($r('app.string.ohos_id_text_size_body1'))}// 原生Text组件Text($r('app.string.mall')).fontSize($r('app.string.ohos_id_text_size_body1'))// 原生Search组件Search({ placeholder: 'Type to search...', controller: this.controller }).searchButton(SEARCH_BUTTON)// 原生Grid组件,Grid中包含Image和TextGrid() {// 性能知识点:此处数据量确定且数量较少,使用了ForEach,在数据量多的情况下,推荐使用LazyForeEachForEach(PRODUCT_DATA, (item: ProductDataModel, index: number) => {GridItem() {Column({ space: MARGIN_VERTICAL }) {Image(item.uri).width($r('app.integer.image_size'))Row({ space: MARGIN_VERTICAL }) {Text(item.title).fontSize($r('app.string.ohos_id_text_size_body3'))Text(item.price).fontSize($r('app.string.ohos_id_text_size_body3'))}}}})}.columnsTemplate('1fr 1fr') // 2列.rowsTemplate('1fr 1fr ') // 2行.rowsGap($r('app.string.ohos_id_elements_margin_vertical_m')) // 行间距.columnsGap($r('app.string.ohos_id_elements_margin_vertical_m')) // 列间距}}
}
  1. embed标签可以在H5页面中嵌入任何类型的内容,在H5界面上通过embed标签标识同层元素,应用侧会将原生组件渲染到H5页面embed标签所在位置。
<div><div id="bodyId"><!-- 在H5界面上通过embed标签标识同层元素,在应用侧将原生组件渲染到H5页面embed标签所在位置--><embed id="nativeSearch" type = "native/component" width="100%" height="100%" src="view"/></div>
</div>
  1. 通过WebView的enableNativeEmbedMode()控制同层渲染开关,通过onNativeEmbedLifecycleChange获取embed标签的生命周期变化数据。
build(){Column() {Stack() {// 性能知识点:此处componentId项确定且数量较少,使用了ForEach,在数据量多的情况下,推荐使用LazyForeEachForEach(this.componentIdArr, (componentId: string) => {NodeContainer(this.nodeControllerMap.get(componentId));}, (embedId: string) => embedId)// web组件加载本地test.html页面Web({ src: $rawfile("view.html"), controller: this.browserTabController }).backgroundColor($r('app.color.ohos_id_color_sub_background'))// 不允许执行缩放.zoomAccess(false)// Todo: 知识点:通过enableNativeEmbedMode()配置同层渲染开关.enableNativeEmbedMode(true)// Todo: 知识点:通过onNativeEmbedLifecycleChange获取embed标签的生命周期变化数据.onNativeEmbedLifecycleChange((embed) => {// 获取web侧embed元素的idconst componentId = embed.info?.id?.toString() as stringif (embed.status === NativeEmbedStatus.CREATE) {// 创建节点控制器,设置参数并rebuildlet nodeController = new SearchNodeController();// 外接纹理与WebView同层渲染nodeController.setRenderOption({surfaceId : embed.surfaceId as string, type : embed.info?.type as string, renderType : NodeRenderType.RENDER_componentTypeTEXTURE, embedId : embed.embedId as string, width : px2vp(embed.info?.width), height : px2vp(embed.info?.height)});nodeController.rebuild();// 根据web传入的embed的id属性作为key,将nodeController存入mapthis.nodeControllerMap.set(componentId, nodeController);// 将web传入的embed的id属性存入@State状态数组变量中,用于动态创建nodeContainer节点容器,需要将push动作放在set之后this.componentIdArr.push(componentId);} else if (embed.status === NativeEmbedStatus.UPDATE) {let nodeController = this.nodeControllerMap.get(componentId);nodeController?.updateNode({text: 'update', width: px2vp(embed.info?.width), height: px2vp(embed.info?.height)} as ESObject);nodeController?.rebuild();} else {let nodeController = this.nodeControllerMap.get(componentId);nodeController?.setBuilderNode(null);nodeController?.rebuild();}})// 获取同层渲染组件触摸事件信息.onNativeEmbedGestureEvent((touch) => {this.componentIdArr.forEach((componentId: string) => {let nodeController = this.nodeControllerMap.get(componentId);if (nodeController?.getEmbedId() === touch.embedId) {nodeController?.postEvent(touch.touchEvent);}})})}}
}
  1. h5侧通过id名获取embed标签信息,并通过embed标签添加同层渲染界面的touch监听事件;应用侧添加onNativeEmbedGestureEvent回调使得手指触摸到embed标签时能获取到触摸事件信息。
let nativeEmbed = {// 通过id名获取embed标签nativeSearch : document.getElementById('nativeSearch'),// 事件events:{},// 初始化init:function(){let self = this;// 添加touch的监听事件self.nativeSearch.addEventListener('touchstart', self.events, false);}
};
nativeEmbed.init();

Web({ src: $rawfile("view.html"), controller: this.browserTabController })// 获取同层渲染组件触摸事件信息.onNativeEmbedGestureEvent((touch) => {this.componentIdArr.forEach((componentId: string) => {let nodeController = this.nodeControllerMap.get(componentId);if (nodeController?.getEmbedId() === touch.embedId) {nodeController?.postEvent(touch.touchEvent);}})})

高性能知识点

ArkWeb同层渲染原生组件,原生组件不仅可以提供H5组件无法实现的一些功能,还能提升用户体验的流畅度;同层渲染节点上下树,实现节点复用,节省节点重复开销。

工程结构&模块类型

nativeembed                            // har类型
|---mock
|   |---GoodsMock.ets                  // 数据源
|---model
|   |---GoodsModel.ets                 // 数据类
|---view
|   |---NativeEmbedView.ets            // 视图层

模块依赖

本实例依赖common模块来实现资源的调用。 依赖动态路由模块来实现页面的动态加载。

参考资料

  1. Web
  2. BuilderNode
  3. NodeController
  4. ArkWeb(方舟Web)

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/767432.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js知识总结

1. JS由那三部分组成&#xff1f; ECMASript文档对象模型&#xff08;DOM&#xff09;浏览器对象模型&#xff08;BOM&#xff09; 2. 操作数组的方法有那些&#xff1f; 高阶函数&#xff1a;map、filter、forEach、reduce、find、findIndex、every、some、push、unshift、…

数据库系统概论(超详解!!!) 第四节 关系数据库标准语言SQL(Ⅰ)

1.SQL概述 SQL&#xff08;Structured Query Language&#xff09;结构化查询语言&#xff0c;是关系数据库的标准语言 SQL是一个通用的、功能极强的关系数据库语言 SQL的动词 基本概念 基本表 &#xff1a;本身独立存在的表&#xff1b; SQL中一个关系就对应一个基本表&am…

SecureCRT:高效安全的远程连接工具

SecureCRT是一款功能强大的终端仿真工具&#xff0c;主要用于连接和运行包括Windows、UNIX和VMS在内的远程系统。它支持多种协议&#xff0c;如SSH1、SSH2、Telnet、SFTP、Rlogin、Serial、SCP等&#xff0c;确保用户与目标设备之间的通信安全&#xff0c;并防止网络攻击和窥探…

spring-boot解析spring.factories文件

spring-boot解析spring.factories文件 启动SpringBoot自动装配的工厂类方法实现 /*** 解析 spring.factories 文件** return 读取到的所有数据*/private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader){try {Enumeration<URL…

HTTP系列之HTTP缓存 —— 强缓存和协商缓存

文章目录 HTTP缓存强缓存协商缓存状态码区别缓存优先级如何设置强缓存和协商缓存使用场景 HTTP缓存 HTTP缓存时利用HTTP响应头将所请求的资源在浏览器进行缓存&#xff0c;缓存方式分两种&#xff1a;强缓存和协商缓存。 浏览器缓存是指将之前请求过的资源在浏览器进行缓存&am…

安卓findViewById 的优化方案:ViewBinding与ButterKnife(一)

好多小伙伴现在还用findViewById来获取控件的id, 在这里提供俩种替代方案&#xff1a;ViewBinding与ButterKnife&#xff1b; 先来说说ButterKnife ButterKnife ButterKnife是一个专注于Android系统的View注入框架&#xff0c;在过去的项目中总是需要很多的findViewById来查…

用C++做一个植物大战僵尸

制作一个完整的“植物大战僵尸”游戏是一个非常大的项目&#xff0c;涉及图形渲染、碰撞检测、用户输入处理、音效、动画、游戏逻辑等多个方面。由于这个话题非常广泛&#xff0c;我可以提供一个简化的版本或者一个框架来启动你的项目。 以下是一个简化的框架&#xff0c;帮助…

java 实现发送邮件功能

今天分享一篇 java 发送 QQ 邮件的功能 环境&#xff1a; jdk 1.8 springboot 2.6.3 maven 3.9.6 邮件功能依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId>&…

idea打包war包部署到tomcat以及访问路径问题

idea将web项目打包成war最重要的是配置atrificats。 首先打开file -》 project structure 创建之后&#xff0c;output directory即为输出war包的路径。Name可以随意&#xff0c;之后点击绿色&#xff0c;打开directory content 选择webapp目录&#xff0c;记得勾选include in…

Python从入门到精通秘籍十七

一、Python的构造方法 在Python中&#xff0c;构造方法是一个特殊的方法&#xff0c;用于创建和初始化类的实例。构造方法的名称是__init__()&#xff0c;它在创建对象时自动调用。 下面是一个示例代码来详细解释Python的构造方法&#xff1a; class Person:def __init__(se…

(C语言)浮点数在内存中的存储详解

1. 浮点数 常见的浮点数&#xff1a;3.14159、 1E10等 &#xff0c;浮点数家族包括&#xff1a; float、double、long double 类型。 浮点数表示的范围&#xff1a; float.h 中定义. 2. 浮点数的存储 我们先来看一串代码&#xff1a; int main() {int n 9;float* pFloa…

安全工具介绍 SCNR/Arachni

关于SCNR 原来叫Arachni 是开源的&#xff0c;现在是SCNR&#xff0c;商用工具了 可试用一个月 Arachni Web Application Security Scanner Framework 看名字就知道了&#xff0c;针对web app 的安全工具&#xff0c;DASTIAST吧 安装 安装之前先 sudo apt-get update sudo…

嵌入式数据库--SQLite

目录 1. SQLite数据库简介 2. SQLite数据库的安装 方式一&#xff1a; 方式二&#xff1a; 3. SQLite的命令用法 1.创建一个数据库 2.创建一张表 3.删除表 4.插入数据 5. 查询数据 6.删除表内一条数据 7.修改表中的数据 8.增加一列也就是增加一个字段 1. SQLite数据库…

C++ 【深基5.例3】冰雹猜想

文章目录 一、题目描述【深基5.例3】冰雹猜想题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示 二、参考代码 一、题目描述 【深基5.例3】冰雹猜想 题目描述 给出一个正整数 n n n&#xff0c;然后对这个数字一直进行下面的操作&#xff1a;如果这个数字是奇数…

LeetCode每日一题——统计桌面上的不同数字

统计桌面上的不同数字OJ链接&#xff1a;2549. 统计桌面上的不同数字 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 思路&#xff1a; 这是一个很简单的数学问题&#xff1a; 当n 5时&#xff0c;因为n % 4 1&#xff0c;所以下一天4一定会被放上桌面 当n 4…

Linux系统 安装docker

安装&#xff1a; 1、Docker要求CentOS系统的内核版本高于 3.10 &#xff0c;通过 uname -r 命令查看你当前的内核版本是否支持安账docker 2、更新yum包&#xff1a; sudo yum -y update 3、安装需要的软件包&#xff0c;yum-util 提供yum-config-manager功能&#xff0c;另外…

kvm虚拟化

kvm虚拟化 1. 虚拟化介绍 虚拟化是云计算的基础。简单的说&#xff0c;虚拟化使得在一台物理的服务器上可以跑多台虚拟机&#xff0c;虚拟机共享物理机的 CPU、内存、IO 硬件资源&#xff0c;但逻辑上虚拟机之间是相互隔离的。 物理机我们一般称为宿主机&#xff08;Host&…

深度学习pytorch——多层感知机反向传播(持续更新)

在讲解多层感知机反向传播之前&#xff0c;先来回顾一下多输出感知机的问题&#xff0c;下图是一个多输出感知机模型&#xff1a; 课时44 反向传播算法-1_哔哩哔哩_bilibili 根据上一次的分析深度学习pytorch——感知机&#xff08;Perceptron&#xff09;&#xff08;持续更新…

trt | TFLOPS TOPS含义

FLOPS是Floating-point Operations Per Second的缩写&#xff0c;代表每秒所执行的浮点运算次数。现在衡量计算能力的标准是TFLOPS&#xff08;每秒万亿次浮点运算&#xff09; NVIDIA显卡算力表&#xff1a;CUDA GPUs - Compute Capability | NVIDIA Developer 例如&#xf…

数学(算法竞赛、蓝桥杯)--快速幂

1、B站视频链接&#xff1a;G01 快速幂_哔哩哔哩_bilibili 题目链接&#xff1a;P1226 【模板】快速幂 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) #include <bits/stdc.h> using namespace std; typedef long long LL; int a,b,p; int quickpow(LL a,int n,int p){…