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

使用说明
- 进入页面即可看到同层渲染效果,Text,search,image都是原生组件。
实现思路
- 添加权限。
"ohos.permission.INTERNET"
- 创建控制器管理绑定的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
| 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
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 添加同层渲染的组件。
@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和Text
Grid() {
// 性能知识点:此处数据量确定且数量较少,使用了ForEach,在数据量多的情况下,推荐使用LazyForeEach
ForEach(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
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- embed标签可以在H5页面中嵌入任何类型的内容,在H5界面上通过embed标签标识同层元素,应用侧会将原生组件渲染到H5页面embed标签所在位置。