1e41f4b71Sopenharmony_ci# BuilderNode
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci## 概述
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ci[BuilderNode](../reference/apis-arkui/js-apis-arkui-builderNode.md)提供能够挂载原生组件的能力,支持通过无状态的UI方法[全局自定义构建函数](../quick-start/arkts-builder.md#全局自定义构建函数)@Builder生成组件树,并通过[getFrameNode](../reference/apis-arkui/js-apis-arkui-builderNode.md#getframenode)获取组件树的根[FrameNode](../reference/apis-arkui/js-apis-arkui-frameNode.md)节点。该节点可以通过[NodeController](../reference/apis-arkui/js-apis-arkui-nodeController.md)直接返回,挂载在[NodeContainer](../reference/apis-arkui/arkui-ts/ts-basic-components-nodecontainer.md)节点下,也可以在FrameNode树结构和[RenderNode](../reference/apis-arkui/js-apis-arkui-renderNode.md)树结构嵌入声明式的组件结构,实现混合显示的能力。同时BuilderNode可以提供纹理导出的功能,导出的纹理用于在[XComponent](../reference/apis-arkui/arkui-ts/ts-basic-components-xcomponent.md)中进行同层渲染显示。
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciBuilderNode创建的ArkTS原生控件树支持与自定义节点(例如:FrameNode、RenderNode)进行关联使用,实现了原生组件与自定义节点的混合显示。对于使用自定义节点的能力进行对接的三方框架,BuilderNode为其提供了嵌入原生组件的能力。
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ciBuilderNode提供了组件预创建的能力,能够自定义原生组件的创建开始的时间,在后续的业务中动态挂载显示。对于一些在创建初始化耗时较长的声明式组件,比如[Web](../reference/apis-arkweb/ts-basic-components-web.md)、[XComponent](../reference/apis-arkui/arkui-ts/ts-basic-components-xcomponent.md)等,预创建可以有效减少组件初始化的耗时。
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci![zh-cn_image_builder-node](figures/builder-node.png)
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ciBuilderNode仅可作为叶子节点进行使用。如有更新需要,建议通过BuilderNode中的Update方式触发更新,不建议通过BuilderNode中获取的RenderNode对节点进行修改操作。
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ci> **说明:**
16e41f4b71Sopenharmony_ci> 
17e41f4b71Sopenharmony_ci> - BuilderNode只支持一个由[wrapBuilder](../quick-start/arkts-wrapBuilder.md)包装的[全局自定义构建函数](../quick-start/arkts-builder.md#全局自定义构建函数)@Builder。
18e41f4b71Sopenharmony_ci> 
19e41f4b71Sopenharmony_ci> - 一个新建的BuildNode在[build](../reference/apis-arkui/js-apis-arkui-builderNode.md#build)之后才能通过[getFrameNode](../reference/apis-arkui/js-apis-arkui-builderNode.md#getframenode)获取到一个指向根节点的FrameNode对象,否则返回null。
20e41f4b71Sopenharmony_ci> 
21e41f4b71Sopenharmony_ci> - 如果传入的Builder的根节点为语法节点(if/else/foreach/...),需要额外生成一个FrameNode,在节点树中的显示为“BuilderProxyNode”。
22e41f4b71Sopenharmony_ci> 
23e41f4b71Sopenharmony_ci> - 如果BuilderNode通过getFrameNode将节点挂载在另一个FrameNode上,或者将其作为子节点挂载在NodeContainer节点上。则节点中使用父组件的布局约束进行布局。
24e41f4b71Sopenharmony_ci> 
25e41f4b71Sopenharmony_ci> - 如果BuilderNode的FrameNode通过[getRenderNode](../reference/apis-arkui/js-apis-arkui-frameNode.md#getrendernode)形式将自己的节点挂载在RenderNode节点上,由于其FrameNode未上树,其大小默认为0,需要通过构造函数中的[selfIdeaSize](../reference/apis-arkui/js-apis-arkui-builderNode.md#renderoptions)显式指定布局约束大小,才能正常显示。
26e41f4b71Sopenharmony_ci> 
27e41f4b71Sopenharmony_ci> - BuilderNode的预加载并不会减少组件的创建时间。Web组件创建的时候需要在内核中加载资源,预创建不能减少Web组件的创建的时间,但是可以让内核进行预加载,减少正式使用时候内核的加载耗时。
28e41f4b71Sopenharmony_ci
29e41f4b71Sopenharmony_ci## 创建BuilderNode对象
30e41f4b71Sopenharmony_ci
31e41f4b71Sopenharmony_ciBuilderNode对象为一个模板类,需要在创建的时候指定类型。该类型需要与后续build方法中传入的[WrappedBuilder](../quick-start/arkts-wrapBuilder.md#wrapbuilder封装全局builder)的类型保持一致,否则会存在编译告警导致编译失败。
32e41f4b71Sopenharmony_ci
33e41f4b71Sopenharmony_ci## 创建原生组件树
34e41f4b71Sopenharmony_ci
35e41f4b71Sopenharmony_ci通过BuilderNode的build可以实现原生组件树的创建。依照传入的WrappedBuilder对象创建组件树,并持有组件树的根节点。
36e41f4b71Sopenharmony_ci
37e41f4b71Sopenharmony_ci> **说明:**
38e41f4b71Sopenharmony_ci>
39e41f4b71Sopenharmony_ci> 无状态的UI方法全局@Builder最多拥有一个根节点。
40e41f4b71Sopenharmony_ci>
41e41f4b71Sopenharmony_ci> build方法中对应的@Builder支持一个参数作为入参。
42e41f4b71Sopenharmony_ci>
43e41f4b71Sopenharmony_ci> build中对于@Builder嵌套@Builder进行使用的场景,需要保证嵌套的参数与build的中提供的入参一致。
44e41f4b71Sopenharmony_ci> 
45e41f4b71Sopenharmony_ci> 对于@Builder嵌套@Builder进行使用的场景,如果入参类型不一致,则要求增加[BuilderOptions](../reference/apis-arkui/js-apis-arkui-builderNode.md#buildoptions12)字段作为[build](../reference/apis-arkui/js-apis-arkui-builderNode.md#build12)的入参。
46e41f4b71Sopenharmony_ci> 
47e41f4b71Sopenharmony_ci> 需要操作BuilderNode中的对象时,需要保证其引用不被回收。当BuilderNode对象被虚拟机回收之后,它的FrameNode、RenderNode对象也会与后端节点解引用。即从BuilderNode中获取的FrameNode对象不对应任何一个节点。
48e41f4b71Sopenharmony_ci
49e41f4b71Sopenharmony_ci创建离线节点以及原生组件树,结合FrameNode进行使用。
50e41f4b71Sopenharmony_ci
51e41f4b71Sopenharmony_ciBuilderNode的根节点直接作为[NodeController](../reference/apis-arkui/js-apis-arkui-nodeController.md)的[makeNode](../reference/apis-arkui/js-apis-arkui-nodeController.md#makenode)返回值。
52e41f4b71Sopenharmony_ci
53e41f4b71Sopenharmony_ci```ts
54e41f4b71Sopenharmony_ciimport { BuilderNode, FrameNode, NodeController, UIContext } from '@kit.ArkUI';
55e41f4b71Sopenharmony_ci
56e41f4b71Sopenharmony_ciclass Params {
57e41f4b71Sopenharmony_ci  text: string = "";
58e41f4b71Sopenharmony_ci
59e41f4b71Sopenharmony_ci  constructor(text: string) {
60e41f4b71Sopenharmony_ci    this.text = text;
61e41f4b71Sopenharmony_ci  }
62e41f4b71Sopenharmony_ci}
63e41f4b71Sopenharmony_ci
64e41f4b71Sopenharmony_ci@Builder
65e41f4b71Sopenharmony_cifunction buildText(params: Params) {
66e41f4b71Sopenharmony_ci  Column() {
67e41f4b71Sopenharmony_ci    Text(params.text)
68e41f4b71Sopenharmony_ci      .fontSize(50)
69e41f4b71Sopenharmony_ci      .fontWeight(FontWeight.Bold)
70e41f4b71Sopenharmony_ci      .margin({ bottom: 36 })
71e41f4b71Sopenharmony_ci  }
72e41f4b71Sopenharmony_ci}
73e41f4b71Sopenharmony_ci
74e41f4b71Sopenharmony_ciclass TextNodeController extends NodeController {
75e41f4b71Sopenharmony_ci  private textNode: BuilderNode<[Params]> | null = null;
76e41f4b71Sopenharmony_ci  private message: string = "DEFAULT";
77e41f4b71Sopenharmony_ci
78e41f4b71Sopenharmony_ci  constructor(message: string) {
79e41f4b71Sopenharmony_ci    super();
80e41f4b71Sopenharmony_ci    this.message = message;
81e41f4b71Sopenharmony_ci  }
82e41f4b71Sopenharmony_ci
83e41f4b71Sopenharmony_ci  makeNode(context: UIContext): FrameNode | null {
84e41f4b71Sopenharmony_ci    this.textNode = new BuilderNode(context);
85e41f4b71Sopenharmony_ci    this.textNode.build(wrapBuilder<[Params]>(buildText), new Params(this.message))
86e41f4b71Sopenharmony_ci    return this.textNode.getFrameNode();
87e41f4b71Sopenharmony_ci  }
88e41f4b71Sopenharmony_ci}
89e41f4b71Sopenharmony_ci
90e41f4b71Sopenharmony_ci@Entry
91e41f4b71Sopenharmony_ci@Component
92e41f4b71Sopenharmony_cistruct Index {
93e41f4b71Sopenharmony_ci  @State message: string = "hello";
94e41f4b71Sopenharmony_ci
95e41f4b71Sopenharmony_ci  build() {
96e41f4b71Sopenharmony_ci    Row() {
97e41f4b71Sopenharmony_ci      Column() {
98e41f4b71Sopenharmony_ci        NodeContainer(new TextNodeController(this.message))
99e41f4b71Sopenharmony_ci          .width('100%')
100e41f4b71Sopenharmony_ci          .height(100)
101e41f4b71Sopenharmony_ci          .backgroundColor('#FFF0F0F0')
102e41f4b71Sopenharmony_ci      }
103e41f4b71Sopenharmony_ci      .width('100%')
104e41f4b71Sopenharmony_ci      .height('100%')
105e41f4b71Sopenharmony_ci    }
106e41f4b71Sopenharmony_ci    .height('100%')
107e41f4b71Sopenharmony_ci  }
108e41f4b71Sopenharmony_ci}
109e41f4b71Sopenharmony_ci```
110e41f4b71Sopenharmony_ci
111e41f4b71Sopenharmony_ci将BuilderNode与RenderNode进行结合使用。
112e41f4b71Sopenharmony_ci
113e41f4b71Sopenharmony_ciBuilderNode的RenderNode挂载其它RenderNode下时,需要明确定义[selfIdeaSize](../reference/apis-arkui/js-apis-arkui-builderNode.md#renderoptions)的大小作为BuilderNode的布局约束。不推荐通过该方式挂载节点。
114e41f4b71Sopenharmony_ci
115e41f4b71Sopenharmony_ci```ts
116e41f4b71Sopenharmony_ciimport { NodeController, BuilderNode, FrameNode, UIContext, RenderNode } from "@kit.ArkUI";
117e41f4b71Sopenharmony_ci
118e41f4b71Sopenharmony_ciclass Params {
119e41f4b71Sopenharmony_ci  text: string = "";
120e41f4b71Sopenharmony_ci
121e41f4b71Sopenharmony_ci  constructor(text: string) {
122e41f4b71Sopenharmony_ci    this.text = text;
123e41f4b71Sopenharmony_ci  }
124e41f4b71Sopenharmony_ci}
125e41f4b71Sopenharmony_ci
126e41f4b71Sopenharmony_ci@Builder
127e41f4b71Sopenharmony_cifunction buildText(params: Params) {
128e41f4b71Sopenharmony_ci  Column() {
129e41f4b71Sopenharmony_ci    Text(params.text)
130e41f4b71Sopenharmony_ci      .fontSize(50)
131e41f4b71Sopenharmony_ci      .fontWeight(FontWeight.Bold)
132e41f4b71Sopenharmony_ci      .margin({ bottom: 36 })
133e41f4b71Sopenharmony_ci  }
134e41f4b71Sopenharmony_ci}
135e41f4b71Sopenharmony_ci
136e41f4b71Sopenharmony_ciclass TextNodeController extends NodeController {
137e41f4b71Sopenharmony_ci  private rootNode: FrameNode | null = null;
138e41f4b71Sopenharmony_ci  private textNode: BuilderNode<[Params]> | null = null;
139e41f4b71Sopenharmony_ci  private message: string = "DEFAULT";
140e41f4b71Sopenharmony_ci
141e41f4b71Sopenharmony_ci  constructor(message: string) {
142e41f4b71Sopenharmony_ci    super();
143e41f4b71Sopenharmony_ci    this.message = message;
144e41f4b71Sopenharmony_ci  }
145e41f4b71Sopenharmony_ci
146e41f4b71Sopenharmony_ci  makeNode(context: UIContext): FrameNode | null {
147e41f4b71Sopenharmony_ci    this.rootNode = new FrameNode(context);
148e41f4b71Sopenharmony_ci    let renderNode = new RenderNode();
149e41f4b71Sopenharmony_ci    renderNode.clipToFrame = false;
150e41f4b71Sopenharmony_ci    this.textNode = new BuilderNode(context, { selfIdealSize: { width: 150, height: 150 } });
151e41f4b71Sopenharmony_ci    this.textNode.build(wrapBuilder<[Params]>(buildText), new Params(this.message));
152e41f4b71Sopenharmony_ci    const textRenderNode = this.textNode?.getFrameNode()?.getRenderNode();
153e41f4b71Sopenharmony_ci
154e41f4b71Sopenharmony_ci    const rootRenderNode = this.rootNode.getRenderNode();
155e41f4b71Sopenharmony_ci    if (rootRenderNode !== null) {
156e41f4b71Sopenharmony_ci      rootRenderNode.appendChild(renderNode);
157e41f4b71Sopenharmony_ci      renderNode.appendChild(textRenderNode);
158e41f4b71Sopenharmony_ci    }
159e41f4b71Sopenharmony_ci
160e41f4b71Sopenharmony_ci    return this.rootNode;
161e41f4b71Sopenharmony_ci  }
162e41f4b71Sopenharmony_ci}
163e41f4b71Sopenharmony_ci
164e41f4b71Sopenharmony_ci@Entry
165e41f4b71Sopenharmony_ci@Component
166e41f4b71Sopenharmony_cistruct Index {
167e41f4b71Sopenharmony_ci  @State message: string = "hello";
168e41f4b71Sopenharmony_ci
169e41f4b71Sopenharmony_ci  build() {
170e41f4b71Sopenharmony_ci    Row() {
171e41f4b71Sopenharmony_ci      Column() {
172e41f4b71Sopenharmony_ci        NodeContainer(new TextNodeController(this.message))
173e41f4b71Sopenharmony_ci          .width('100%')
174e41f4b71Sopenharmony_ci          .height(100)
175e41f4b71Sopenharmony_ci          .backgroundColor('#FFF0F0F0')
176e41f4b71Sopenharmony_ci      }
177e41f4b71Sopenharmony_ci      .width('100%')
178e41f4b71Sopenharmony_ci      .height('100%')
179e41f4b71Sopenharmony_ci    }
180e41f4b71Sopenharmony_ci    .height('100%')
181e41f4b71Sopenharmony_ci  }
182e41f4b71Sopenharmony_ci}
183e41f4b71Sopenharmony_ci```
184e41f4b71Sopenharmony_ci
185e41f4b71Sopenharmony_ci## 更新原生组件树
186e41f4b71Sopenharmony_ci
187e41f4b71Sopenharmony_ci通过BuilderNode对象的build创建原生组件树。依照传入的WrappedBuilder对象创建组件树,并持有组件树的根节点。
188e41f4b71Sopenharmony_ci
189e41f4b71Sopenharmony_ci自定义组件的更新遵循[状态管理](../quick-start/arkts-state-management-overview.md)的更新机制。WrappedBuilder中直接使用的自定义组件其父组件为BuilderNode对象。因此,更新子组件即WrappedBuilder中定义的自定义组件,需要遵循状态管理的定义将相关的状态变量定义为[\@Prop](../quick-start/arkts-prop.md)或者[\@ObjectLink](../quick-start/arkts-observed-and-objectlink.md)。装饰器的选择请参照状态管理的装饰器规格结合应用开发需求进行选择。
190e41f4b71Sopenharmony_ci
191e41f4b71Sopenharmony_ci
192e41f4b71Sopenharmony_ci使用update更新BuilderNode中的节点。
193e41f4b71Sopenharmony_ci
194e41f4b71Sopenharmony_ci使用[updateConfiguration](../reference/apis-arkui/js-apis-arkui-builderNode.md#updateconfiguration12)触发BuilderNode中节点的全量更新。
195e41f4b71Sopenharmony_ci
196e41f4b71Sopenharmony_ci更新BuilderNode中的节点。
197e41f4b71Sopenharmony_ci
198e41f4b71Sopenharmony_ci```ts
199e41f4b71Sopenharmony_ciimport { NodeController, BuilderNode, FrameNode, UIContext } from "@kit.ArkUI";
200e41f4b71Sopenharmony_ci
201e41f4b71Sopenharmony_ciclass Params {
202e41f4b71Sopenharmony_ci  text: string = "";
203e41f4b71Sopenharmony_ci  constructor(text: string) {
204e41f4b71Sopenharmony_ci    this.text = text;
205e41f4b71Sopenharmony_ci  }
206e41f4b71Sopenharmony_ci}
207e41f4b71Sopenharmony_ci
208e41f4b71Sopenharmony_ci// 自定义组件
209e41f4b71Sopenharmony_ci@Component
210e41f4b71Sopenharmony_cistruct TextBuilder {
211e41f4b71Sopenharmony_ci  // 作为自定义组件中需要更新的属性,数据类型为基础属性,定义为@Prop
212e41f4b71Sopenharmony_ci  @Prop message: string = "TextBuilder";
213e41f4b71Sopenharmony_ci
214e41f4b71Sopenharmony_ci  build() {
215e41f4b71Sopenharmony_ci    Row() {
216e41f4b71Sopenharmony_ci      Column() {
217e41f4b71Sopenharmony_ci        Text(this.message)
218e41f4b71Sopenharmony_ci          .fontSize(50)
219e41f4b71Sopenharmony_ci          .fontWeight(FontWeight.Bold)
220e41f4b71Sopenharmony_ci          .margin({ bottom: 36 })
221e41f4b71Sopenharmony_ci          .backgroundColor(Color.Gray)
222e41f4b71Sopenharmony_ci      }
223e41f4b71Sopenharmony_ci    }
224e41f4b71Sopenharmony_ci  }
225e41f4b71Sopenharmony_ci}
226e41f4b71Sopenharmony_ci
227e41f4b71Sopenharmony_ci@Builder
228e41f4b71Sopenharmony_cifunction buildText(params: Params) {
229e41f4b71Sopenharmony_ci  Column() {
230e41f4b71Sopenharmony_ci    Text(params.text)
231e41f4b71Sopenharmony_ci      .fontSize(50)
232e41f4b71Sopenharmony_ci      .fontWeight(FontWeight.Bold)
233e41f4b71Sopenharmony_ci      .margin({ bottom: 36 })
234e41f4b71Sopenharmony_ci    TextBuilder({ message: params.text }) // 自定义组件
235e41f4b71Sopenharmony_ci  }
236e41f4b71Sopenharmony_ci}
237e41f4b71Sopenharmony_ci
238e41f4b71Sopenharmony_ciclass TextNodeController extends NodeController {
239e41f4b71Sopenharmony_ci  private textNode: BuilderNode<[Params]> | null = null;
240e41f4b71Sopenharmony_ci  private message: string = "";
241e41f4b71Sopenharmony_ci
242e41f4b71Sopenharmony_ci  constructor(message: string) {
243e41f4b71Sopenharmony_ci    super()
244e41f4b71Sopenharmony_ci    this.message = message
245e41f4b71Sopenharmony_ci  }
246e41f4b71Sopenharmony_ci
247e41f4b71Sopenharmony_ci  makeNode(context: UIContext): FrameNode | null {
248e41f4b71Sopenharmony_ci    this.textNode = new BuilderNode(context);
249e41f4b71Sopenharmony_ci    this.textNode.build(wrapBuilder<[Params]>(buildText), new Params(this.message))
250e41f4b71Sopenharmony_ci    return this.textNode.getFrameNode();
251e41f4b71Sopenharmony_ci  }
252e41f4b71Sopenharmony_ci
253e41f4b71Sopenharmony_ci  update(message: string) {
254e41f4b71Sopenharmony_ci    if (this.textNode !== null) {
255e41f4b71Sopenharmony_ci      // 调用update进行更新。
256e41f4b71Sopenharmony_ci      this.textNode.update(new Params(message));
257e41f4b71Sopenharmony_ci    }
258e41f4b71Sopenharmony_ci  }
259e41f4b71Sopenharmony_ci}
260e41f4b71Sopenharmony_ci
261e41f4b71Sopenharmony_ci@Entry
262e41f4b71Sopenharmony_ci@Component
263e41f4b71Sopenharmony_cistruct Index {
264e41f4b71Sopenharmony_ci  @State message: string = "hello";
265e41f4b71Sopenharmony_ci  private textNodeController: TextNodeController = new TextNodeController(this.message);
266e41f4b71Sopenharmony_ci  private count = 0;
267e41f4b71Sopenharmony_ci
268e41f4b71Sopenharmony_ci  build() {
269e41f4b71Sopenharmony_ci    Row() {
270e41f4b71Sopenharmony_ci      Column() {
271e41f4b71Sopenharmony_ci        NodeContainer(this.textNodeController)
272e41f4b71Sopenharmony_ci          .width('100%')
273e41f4b71Sopenharmony_ci          .height(200)
274e41f4b71Sopenharmony_ci          .backgroundColor('#FFF0F0F0')
275e41f4b71Sopenharmony_ci        Button('Update')
276e41f4b71Sopenharmony_ci          .onClick(() => {
277e41f4b71Sopenharmony_ci            this.count += 1;
278e41f4b71Sopenharmony_ci            const message = "Update " + this.count.toString();
279e41f4b71Sopenharmony_ci            this.textNodeController.update(message);
280e41f4b71Sopenharmony_ci          })
281e41f4b71Sopenharmony_ci      }
282e41f4b71Sopenharmony_ci      .width('100%')
283e41f4b71Sopenharmony_ci      .height('100%')
284e41f4b71Sopenharmony_ci    }
285e41f4b71Sopenharmony_ci    .height('100%')
286e41f4b71Sopenharmony_ci  }
287e41f4b71Sopenharmony_ci}
288e41f4b71Sopenharmony_ci```
289e41f4b71Sopenharmony_ci
290e41f4b71Sopenharmony_ci## 解除实体节点引用关系
291e41f4b71Sopenharmony_ci
292e41f4b71Sopenharmony_ci由于BuilderNode对应的是后端的实体节点,正常的内存释放依赖前端对象的回收。如果期望直接释放后端的节点对象,则可以通过调用[dispose](../reference/apis-arkui/js-apis-arkui-builderNode.md#dispose12)与实体节点解除引用关系,此时持有的前端BuilderNode对象不再影响实体节点的生命周期。
293e41f4b71Sopenharmony_ci
294e41f4b71Sopenharmony_ci> **说明:**
295e41f4b71Sopenharmony_ci>
296e41f4b71Sopenharmony_ci> 当BuilderNode对象调用dispose之后,不仅BuilderNode对象与后端实体节点解除引用关系,BuilderNode中的FrameNode与RenderNode也会同步和实体节点解除引用关系。
297e41f4b71Sopenharmony_ci
298e41f4b71Sopenharmony_ci## 注入触摸事件
299e41f4b71Sopenharmony_ci
300e41f4b71Sopenharmony_ciBuilderNode中提供了[postTouchEvent](../reference/apis-arkui/js-apis-arkui-builderNode.md#posttouchevent),可以通过该接口向BuilderNode中绑定的组件注入[触摸事件](../reference/apis-arkui/arkui-ts/ts-universal-events-touch.md#触摸事件),实现事件的模拟转发。
301e41f4b71Sopenharmony_ci
302e41f4b71Sopenharmony_ci通过postTouchEvent向BuilderNode对应的节点树中注入触摸事件。
303e41f4b71Sopenharmony_ci
304e41f4b71Sopenharmony_ci向BuilderNode中的Column组件转发另一个Column的接收事件,即点击下方的Column组件,上方的Colum组件也会收到同样的触摸事件。当Button中的事件被成功识别的时候,返回值为true。
305e41f4b71Sopenharmony_ci
306e41f4b71Sopenharmony_ci```ts
307e41f4b71Sopenharmony_ciimport { NodeController, BuilderNode, FrameNode, UIContext } from '@kit.ArkUI';
308e41f4b71Sopenharmony_ci
309e41f4b71Sopenharmony_ciclass Params {
310e41f4b71Sopenharmony_ci  text: string = "this is a text";
311e41f4b71Sopenharmony_ci}
312e41f4b71Sopenharmony_ci
313e41f4b71Sopenharmony_ci@Builder
314e41f4b71Sopenharmony_cifunction ButtonBuilder(params: Params) {
315e41f4b71Sopenharmony_ci  Column() {
316e41f4b71Sopenharmony_ci    Button(`button ` + params.text)
317e41f4b71Sopenharmony_ci      .borderWidth(2)
318e41f4b71Sopenharmony_ci      .backgroundColor(Color.Orange)
319e41f4b71Sopenharmony_ci      .width("100%")
320e41f4b71Sopenharmony_ci      .height("100%")
321e41f4b71Sopenharmony_ci      .gesture(
322e41f4b71Sopenharmony_ci        TapGesture()
323e41f4b71Sopenharmony_ci          .onAction((event: GestureEvent) => {
324e41f4b71Sopenharmony_ci            console.log("TapGesture");
325e41f4b71Sopenharmony_ci          })
326e41f4b71Sopenharmony_ci      )
327e41f4b71Sopenharmony_ci  }
328e41f4b71Sopenharmony_ci  .width(500)
329e41f4b71Sopenharmony_ci  .height(300)
330e41f4b71Sopenharmony_ci  .backgroundColor(Color.Gray)
331e41f4b71Sopenharmony_ci}
332e41f4b71Sopenharmony_ci
333e41f4b71Sopenharmony_ciclass MyNodeController extends NodeController {
334e41f4b71Sopenharmony_ci  private rootNode: BuilderNode<[Params]> | null = null;
335e41f4b71Sopenharmony_ci  private wrapBuilder: WrappedBuilder<[Params]> = wrapBuilder(ButtonBuilder);
336e41f4b71Sopenharmony_ci
337e41f4b71Sopenharmony_ci  makeNode(uiContext: UIContext): FrameNode | null {
338e41f4b71Sopenharmony_ci    this.rootNode = new BuilderNode(uiContext);
339e41f4b71Sopenharmony_ci    this.rootNode.build(this.wrapBuilder, { text: "this is a string" })
340e41f4b71Sopenharmony_ci    return this.rootNode.getFrameNode();
341e41f4b71Sopenharmony_ci  }
342e41f4b71Sopenharmony_ci
343e41f4b71Sopenharmony_ci  postTouchEvent(touchEvent: TouchEvent): void {
344e41f4b71Sopenharmony_ci    if (this.rootNode == null) {
345e41f4b71Sopenharmony_ci      return;
346e41f4b71Sopenharmony_ci    }
347e41f4b71Sopenharmony_ci    let result = this.rootNode.postTouchEvent(touchEvent);
348e41f4b71Sopenharmony_ci    console.log("result " + result);
349e41f4b71Sopenharmony_ci  }
350e41f4b71Sopenharmony_ci}
351e41f4b71Sopenharmony_ci
352e41f4b71Sopenharmony_ci@Entry
353e41f4b71Sopenharmony_ci@Component
354e41f4b71Sopenharmony_cistruct MyComponent {
355e41f4b71Sopenharmony_ci  private nodeController: MyNodeController = new MyNodeController();
356e41f4b71Sopenharmony_ci
357e41f4b71Sopenharmony_ci  build() {
358e41f4b71Sopenharmony_ci    Column() {
359e41f4b71Sopenharmony_ci      NodeContainer(this.nodeController)
360e41f4b71Sopenharmony_ci        .height(300)
361e41f4b71Sopenharmony_ci        .width(500)
362e41f4b71Sopenharmony_ci      Column()
363e41f4b71Sopenharmony_ci        .width(500)
364e41f4b71Sopenharmony_ci        .height(300)
365e41f4b71Sopenharmony_ci        .backgroundColor(Color.Pink)
366e41f4b71Sopenharmony_ci        .onTouch((event) => {
367e41f4b71Sopenharmony_ci          if (event != undefined) {
368e41f4b71Sopenharmony_ci            this.nodeController.postTouchEvent(event);
369e41f4b71Sopenharmony_ci          }
370e41f4b71Sopenharmony_ci        })
371e41f4b71Sopenharmony_ci    }
372e41f4b71Sopenharmony_ci  }
373e41f4b71Sopenharmony_ci}
374e41f4b71Sopenharmony_ci```
375e41f4b71Sopenharmony_ci
376