FrameNode

FrameNode表示组件树的实体节点。NodeController可通过BuilderNode持有的FrameNode将其挂载到NodeContainer上,也可通过FrameNode获取RenderNode,挂载到其他FrameNode上。最佳实践请参考组件动态创建-组件动态添加、更新和删除

说明:

本模块首批接口从API version 11开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。

当前不支持在预览器中使用FrameNode节点。

FrameNode节点暂不支持拖拽。

导入模块

import { FrameNode, LayoutConstraint, ExpandMode, typeNode, NodeAdapter } from "@kit.ArkUI";

CrossLanguageOptions15+

该接口用于配置或查询FrameNode的跨语言访问权限。例如,针对ArkTS语言创建的节点,可通过该接口控制是否允许通过非ArkTS语言进行属性访问或修改。

原子化服务API: 从API version 15开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

名称 类型 只读 可选 说明
attributeSetting boolean FrameNode是否支持跨ArkTS语言进行属性设置。
true表示支持跨ArkTS语言进行属性设置,false表示不支持跨ArkTS语言进行属性设置。
默认为false。

ExpandMode15+

子节点展开模式枚举。

原子化服务API: 从API version 15开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

名称 说明
NOT_EXPAND 0 表示不展开当前FrameNode的子节点。如果FrameNode包含LazyForEach子节点,获取在主节点树上的子节点时,不展开当前FrameNode的子节点。子节点序列号按在主节点树上的子节点计算。
EXPAND 1 表示展开当前FrameNode的子节点。如果FrameNode包含LazyForEach子节点,获取所有子节点时,展开当前FrameNode的子节点。子节点序列号按所有子节点计算。
LAZY_EXPAND 2 表示按需展开当前FrameNode的子节点。如果FrameNode包含LazyForEach子节点,获取在主树上的子节点时,不展开当前FrameNode的子节点;获取不在主树上的子节点时,展开当前FrameNode的子节点。子节点序列号按所有子节点计算。

FrameNode

constructor

constructor(uiContext: UIContext)

FrameNode的构造函数。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
uiContext UIContext 创建对应节点时所需的UI上下文。

getRenderNode

getRenderNode(): RenderNode | null

获取FrameNode中持有的RenderNode。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
RenderNode | null 一个RenderNode对象。若该FrameNode不包含RenderNode,则返回空对象null。如果当前FrameNode为声明式组件创建的节点,则返回null。

示例:

import { NodeController, FrameNode } from '@kit.ArkUI';

class MyNodeController extends NodeController {
  private rootNode: FrameNode | null = null;

  makeNode(uiContext: UIContext): FrameNode | null {
    this.rootNode = new FrameNode(uiContext);

    const renderNode = this.rootNode.getRenderNode();
    if (renderNode !== null) {
      renderNode.size = { width: 100, height: 100 };
      renderNode.backgroundColor = 0XFFFF0000;
    }

    return this.rootNode;
  }
}

@Entry
@Component
struct Index {
  private myNodeController: MyNodeController = new MyNodeController();

  build() {
    Row() {
      NodeContainer(this.myNodeController)
    }
  }
}

isModifiable12+

isModifiable(): boolean

判断当前节点是否可修改。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
boolean 判断当前节点是否可修改。
true表示当前节点可修改,false表示当前节点不可修改。
当节点为系统组件的代理节点或节点已经dispose时返回false。
当返回false时,当前FrameNode不支持appendChild、insertChildAfter、removeChild、clearChildren、createAnimation、cancelAnimations的操作。

示例:

请参考节点操作示例

appendChild12+

appendChild(node: FrameNode): void

在FrameNode最后一个子节点后添加新的子节点。当前FrameNode如果不可修改,抛出异常信息。typeNode在appendChild时会校验子组件类型或个数,不满足抛出异常信息,限制情况请查看typeNode描述。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
node FrameNode 需要添加的FrameNode。
说明:
node节点不可以为声明式创建的节点,即不可修改的FrameNode。仅有从BuilderNode中获取的声明式节点可以作为子节点。若子节点不符合规格,则抛出异常信息。
node节点不可以拥有父节点,否则抛出异常信息。

错误码:

错误码ID 错误信息
100021 The FrameNode is not modifiable.

示例:

请参考节点操作示例

insertChildAfter12+

insertChildAfter(child: FrameNode, sibling: FrameNode | null): void

在FrameNode指定子节点之后添加新的子节点。当前FrameNode如果不可修改,抛出异常信息。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
child FrameNode 需要添加的子节点。
说明:
child节点不可以为声明式创建的节点,即不可修改的FrameNode。仅有从BuilderNode中获取的声明式节点可以作为子节点。若子节点不符合规格,则抛出异常信息。
child节点不可以拥有父节点,否则抛出异常信息。
sibling FrameNode | null 新节点将插入到该节点之后。若该参数设置为空,则新节点将插入到首个子节点之前。

错误码:

错误码ID 错误信息
100021 The FrameNode is not modifiable.

示例:

请参考节点操作示例

removeChild12+

removeChild(node: FrameNode): void

从FrameNode中删除指定的子节点。当前FrameNode如果不可修改,抛出异常信息。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
node FrameNode 需要删除的子节点。

错误码:

错误码ID 错误信息
100021 The FrameNode is not modifiable.

示例:

请参考节点操作示例

clearChildren12+

clearChildren(): void

清除当前FrameNode的所有子节点。当前FrameNode如果不可修改,抛出异常信息。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

错误码:

错误码ID 错误信息
100021 The FrameNode is not modifiable.

示例:

请参考节点操作示例

getChild12+

getChild(index: number): FrameNode | null

获取当前节点指定位置的子节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
index number 需要查询的子节点的序列号。
若当前节点有n个子节点,index取值范围为[0, n-1]。

返回值:

类型 说明
FrameNode | null 子节点。若该FrameNode不包含所查询的子节点,则返回空对象null。

示例:

请参考节点操作示例

getChild15+

getChild(index: number, expandMode?: ExpandMode): FrameNode | null

获取当前节点指定位置的子节点,支持指定子节点展开模式。

原子化服务API: 从API version 15开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
index number 需要查询的子节点的序列号。
若当前节点有n个子节点,index取值范围为[0, n-1]。
expandMode ExpandMode 指定子节点展开模式。
默认值:ExpandMode.EXPAND

返回值:

类型 说明
FrameNode | null 子节点。若该FrameNode不包含所查询的子节点,则返回空对象null。

示例:

请参考LazyForEach场景节点操作示例

getFirstChildIndexWithoutExpand15+

getFirstChildIndexWithoutExpand(): number

获取当前节点第一个在主节点树上的子节点的序列号。子节点序列号按所有子节点计算。

原子化服务API: 从API version 15开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
number 当前节点第一个在主节点树上的子节点的序列号。

示例:

请参考LazyForEach场景节点操作示例

getLastChildIndexWithoutExpand15+

getLastChildIndexWithoutExpand(): number

获取当前节点最后一个在主节点树上的子节点的序列号。子节点序列号按所有子节点计算。

原子化服务API: 从API version 15开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
number 当前节点最后一个在主节点树上的子节点的序列号。

示例:

请参考LazyForEach场景节点操作示例

getFirstChild12+

getFirstChild(): FrameNode | null

获取当前FrameNode的第一个子节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
FrameNode | null 首个子节点。若该FrameNode不包含子节点,则返回空对象null。

示例:

请参考节点操作示例

getNextSibling12+

getNextSibling(): FrameNode | null

获取当前FrameNode的下一个同级节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
FrameNode | null 当前FrameNode的下一个同级节点。若该FrameNode不包含下一个同级节点,则返回空对象null。

示例:

请参考节点操作示例

getPreviousSibling12+

getPreviousSibling(): FrameNode | null

获取当前FrameNode的上一个同级节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
FrameNode | null 当前FrameNode的上一个同级节点。若该FrameNode不包含上一个同级节点,则返回空对象null。

示例:

请参考节点操作示例

getParent12+

getParent(): FrameNode | null

获取当前FrameNode的父节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
FrameNode | null 当前FrameNode的父节点。若该FrameNode不包含父节点,则返回空对象null。

示例:

请参考节点操作示例获取根节点示例

getChildrenCount12+

getChildrenCount(): number

获取当前FrameNode的子节点数量。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
number 获取当前FrameNode的子节点数量。

示例:

请参考节点操作示例

moveTo18+

moveTo(targetParent: FrameNode, index?: number): void

将当前FrameNode移动到目标FrameNode的指定位置。当前FrameNode如果不可修改,抛出异常信息。targetParent为typeNode时会校验子组件类型或个数,不满足抛出异常信息,限制情况请查看typeNode描述。

说明:

当前仅支持以下类型的TypedFrameNode进行移动操作:StackXComponent。对于其他类型的节点,移动操作不会生效。

当前仅支持根节点为以下类型组件的BuilderNode进行移动操作:StackXComponentEmbeddedComponent。对于其他类型的组件,移动操作不会生效。

原子化服务API: 从API version 18开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
targetParent FrameNode 目标父节点。
说明:
targetParent节点不可以为声明式创建的节点,即不可修改的FrameNode。若目标父节点不符合规格,则抛出异常信息。
index number 子节点序列号。当前FrameNode将被添加到目标FrameNode对应序列号的子节点之前,若目标FrameNode有n个节点,index取值范围为[0, n-1]。
若参数无效或不指定,则添加到目标FrameNode的最后。
默认值:-1

错误码:

错误码ID 错误信息
100021 The FrameNode is not modifiable.

示例:

请参考节点操作示例

getPositionToWindow12+

getPositionToWindow(): Position

获取FrameNode相对于窗口的位置偏移,单位为VP。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
Position 节点相对于窗口的位置偏移,单位为VP。

示例:

请参考节点操作示例

getPositionToParent12+

getPositionToParent(): Position

获取FrameNode相对于父组件的位置偏移,单位为VP。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
Position 节点相对于父组件的位置偏移,单位为VP。

示例:

请参考节点操作示例

getPositionToScreen12+

getPositionToScreen(): Position

获取FrameNode相对于屏幕的位置偏移,单位为VP。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
Position 节点相对于屏幕的位置偏移,单位为VP。

示例:

请参考节点操作示例

getPositionToParentWithTransform12+

getPositionToParentWithTransform(): Position

获取FrameNode相对于父组件带有绘制属性的位置偏移,单位为VP,绘制属性比如transform, translate等,返回的坐标是组件布局时左上角变换后的坐标。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
Position 节点相对于父组件的位置偏移,单位为VP。 当设置了其他(比如:transform, translate等)绘制属性,由于浮点数精度的影响,返回值会有微小偏差。

示例:

请参考节点操作示例

getPositionToWindowWithTransform12+

getPositionToWindowWithTransform(): Position

获取FrameNode相对于窗口带有绘制属性的位置偏移,单位为VP,绘制属性比如transform, translate等,返回的坐标是组件布局时左上角变换后的坐标。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
Position 节点相对于窗口的位置偏移,单位为VP。 当设置了其他(比如:transform, translate等)绘制属性,由于浮点数精度的影响,返回值会有微小偏差。

示例:

请参考节点操作示例

getPositionToScreenWithTransform12+

getPositionToScreenWithTransform(): Position

获取FrameNode相对于屏幕带有绘制属性的位置偏移,单位为VP,绘制属性比如transform, translate等,返回的坐标是组件布局时左上角变换后的坐标。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
Position 节点相对于屏幕的位置偏移,单位为VP。 当设置了其他(比如:transform, translate等)绘制属性,由于浮点数精度的影响,返回值会有微小偏差。

示例:

请参考节点操作示例

getMeasuredSize12+

getMeasuredSize(): Size

获取FrameNode测量后的大小,单位为PX。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
Size 节点测量后的大小,单位为PX。

示例:

请参考节点操作示例

getLayoutPosition12+

getLayoutPosition(): Position

获取FrameNode布局后相对于父组件的位置偏移,单位为PX。该偏移是父容器对该节点进行布局之后的结果,因此布局之后生效的offset属性和不参与布局的position属性不影响该偏移值。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
Position 节点布局后相对于父组件的位置偏移,单位为PX。

示例:

请参考节点操作示例

getUserConfigBorderWidth12+

getUserConfigBorderWidth(): Edges<LengthMetrics>

获取用户设置的边框宽度。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
Edges<LengthMetrics> 用户设置的边框宽度。

示例:

请参考节点操作示例

getUserConfigPadding12+

getUserConfigPadding(): Edges<LengthMetrics>

获取用户设置的内边距。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
Edges<LengthMetrics> 用户设置的内边距。

示例:

请参考节点操作示例

getUserConfigMargin12+

getUserConfigMargin(): Edges<LengthMetrics>

获取用户设置的外边距。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
Edges<LengthMetrics> 用户设置的外边距。

示例:

请参考节点操作示例

getUserConfigSize12+

getUserConfigSize(): SizeT<LengthMetrics>

获取用户设置的宽高。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
SizeT<LengthMetrics> 用户设置的宽高。

示例:

请参考节点操作示例

getId12+

getId(): string

获取用户设置的节点ID(通用属性设置的ID)。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
string 用户设置的节点ID(通用属性设置的ID)。

示例:

请参考节点操作示例

getUniqueId12+

getUniqueId(): number

获取系统分配的唯一标识的节点UniqueID。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
number 系统分配的唯一标识的节点UniqueID。

示例:

请参考节点操作示例

getNodeType12+

getNodeType(): string

获取节点的类型。系统组件类型为组件名称,例如,按钮组件Button的类型为Button。而对于自定义组件,若其有渲染内容,则其类型为__Common__。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
string 节点的类型。

示例:

请参考节点操作示例

getOpacity12+

getOpacity(): number

获取节点的不透明度,最小值为0,最大值为1。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
number 节点的不透明度。范围是[0, 1],值越大透明度越低。

示例:

请参考节点操作示例

isVisible12+

isVisible(): boolean

获取节点是否可见。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
boolean 节点是否可见。
true表示节点可见,false表示节点不可见。

示例:

请参考节点操作示例

isClipToFrame12+

isClipToFrame(): boolean

获取节点是否是剪裁到组件区域。当调用dispose解除对实体FrameNode节点的引用关系之后,返回值为true。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
boolean 节点是否是剪裁到组件区域。
true表示节点剪裁到组件区域,false表示节点不是剪裁到组件区域。

示例:

请参考节点操作示例

isAttached12+

isAttached(): boolean

获取节点是否被挂载到主节点树上。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
boolean 节点是否被挂载到主节点树上。
true表示节点被挂载到主节点树上,false表示节点不是被挂载到主节点树上。

示例:

请参考节点操作示例

getInspectorInfo12+

getInspectorInfo(): Object

获取节点的结构信息,该信息和DevEco Studio内置ArkUI Inspector工具里面的一致。

说明:

getInspectorInfo接口用于获取所有节点的信息,作为调试接口使用,频繁调用会导致性能下降。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
Object 节点的结构信息。

以查询Button组件节点为例获取到的Object结果部分值如下所示

{
    "$type": "Button",
    "$ID": 44,
    "type": "build-in",
    "$rect": "[498.00, 468.00],[718.00,598.00]",
    "$debugLine": "",
    "$attrs": {
        "borderStyle": "BorderStyle.Solid",
        "borderColor": "#FF000000",
        "borderWidth": "0.00vp",
        "borderRadius": {
            "topLeft": "65.00px",
            "topRight": "65.00px",
            "bottomLeft": "65.00px",
            "bottomRight": "65.00px"
        },
        "border": "{\"style\":\"BorderStyle.Solid\",\"color\":\"#FF000000\",\"width\":\"0.00vp\",\"radius\":{\"topLeft\":\"65.00px\",\"topRight\":\"65.00px\",\"bottomLeft\":\"65.00px\",\"bottomRight\":\"65.00px\"},\"dashGap\":\"0.00vp\",\"dashWidth\":\"0.00vp\"}",
        "outlineStyle": "OutlineStyle.SOLID",
        "outlineColor": "#FF000000"
    }
}

以上返回结果的$attrs字段会根据不同的组件类型具有不同的属性,具体可以参考getInspectorInfo返回结果$attrs映射表.xlsx

示例:

请参考节点操作示例

getCustomProperty12+

getCustomProperty(name: string): Object | undefined

通过名称获取组件的自定义属性。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
name string 自定义属性的名称。

返回值:

类型 说明
Object | undefined 自定义属性的值。

示例:

请参考节点操作示例

dispose12+

dispose(): void

立即解除当前FrameNode对象对实体FrameNode节点的引用关系。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

说明:

FrameNode对象调用dispose后,由于不对应任何实体FrameNode节点,在调用部分查询接口(getMeasuredSizegetLayoutPosition)的时候会导致应用出现jscrash。

通过getUniqueId可以判断当前FrameNode是否对应一个实体FrameNode节点。当UniqueId大于0时表示该对象对应一个实体FrameNode节点。

示例:

import { NodeController, FrameNode, BuilderNode } from '@kit.ArkUI';

@Component
struct TestComponent {
  build() {
    Column() {
      Text('This is a BuilderNode.')
        .fontSize(16)
        .fontWeight(FontWeight.Bold)
    }
    .width('100%')
    .backgroundColor(Color.Gray)
  }

  aboutToAppear() {
    console.error('aboutToAppear');
  }

  aboutToDisappear() {
    console.error('aboutToDisappear');
  }
}

@Builder
function buildComponent() {
  TestComponent()
}

class MyNodeController extends NodeController {
  private rootNode: FrameNode | null = null;
  private builderNode: BuilderNode<[]> | null = null;

  makeNode(uiContext: UIContext): FrameNode | null {
    this.rootNode = new FrameNode(uiContext);
    this.builderNode = new BuilderNode(uiContext, { selfIdealSize: { width: 200, height: 100 } });
    this.builderNode.build(new WrappedBuilder(buildComponent));

    const rootRenderNode = this.rootNode.getRenderNode();
    if (rootRenderNode !== null) {
      rootRenderNode.size = { width: 200, height: 200 };
      rootRenderNode.backgroundColor = 0xff00ff00;
      rootRenderNode.appendChild(this.builderNode!.getFrameNode()!.getRenderNode());
    }

    return this.rootNode;
  }

  disposeFrameNode() {
    if (this.rootNode !== null && this.builderNode !== null) {
      this.rootNode.removeChild(this.builderNode.getFrameNode());
      this.builderNode.dispose();

      this.rootNode.dispose();
    }
  }

  removeBuilderNode() {
    const rootRenderNode = this.rootNode!.getRenderNode();
    if (rootRenderNode !== null && this.builderNode !== null && this.builderNode.getFrameNode() !== null) {
      rootRenderNode.removeChild(this.builderNode!.getFrameNode()!.getRenderNode());
    }
  }
}

@Entry
@Component
struct Index {
  private myNodeController: MyNodeController = new MyNodeController();

  build() {
    Column({ space: 4 }) {
      NodeContainer(this.myNodeController)
      Button('FrameNode dispose')
        .onClick(() => {
          this.myNodeController.disposeFrameNode();
        })
        .width('100%')
    }
  }
}

commonAttribute12+

get commonAttribute(): CommonAttribute

获取FrameNode中持有的CommonAttribute接口,用于设置通用属性。

仅可以修改自定义节点的属性。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
CommonAttribute 获取FrameNode中持有的CommonAttribute接口,用于设置通用属性。

说明:

FrameNode的效果参考对齐方式为顶部起始端的Stack容器组件。

FrameNode的属性支持范围参考CommonModifier

示例:

请参考基础事件示例

commonEvent12+

get commonEvent(): UICommonEvent

获取FrameNode中持有的UICommonEvent对象,用于设置基础事件。设置的基础事件与声明式定义的事件平行,参与事件竞争;设置的基础事件不覆盖原有的声明式事件。同时设置两个事件回调的时候,优先回调声明式事件。

LazyForEach场景下,由于存在节点的销毁重建,对于重建的节点需要重新设置事件回调才能保证监听事件正常响应。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
UICommonEvent UICommonEvent对象,用于设置基础事件。

示例:

请参考基础事件示例LazyForEach场景基础事件使用示例

gestureEvent14+

get gestureEvent(): UIGestureEvent

获取FrameNode中持有的UIGestureEvent对象,用于设置组件绑定的手势事件。通过gestureEvent接口设置的手势不会覆盖通过声明式手势接口绑定的手势,两者同时设置了手势时,优先回调声明式接口设置的手势事件。

原子化服务API: 从API version 14开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
UIGestureEvent UIGestureEvent对象,用于设置组件绑定的手势。

示例:

请参考手势事件示例

onDraw12+

onDraw?(context: DrawContext): void

FrameNode的自绘制方法,该方法会重写默认绘制方法,在FrameNode进行内容绘制时被调用。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context DrawContext 图形绘制上下文。自绘制区域无法超出组件自身大小。

示例:

请参考节点自定义示例

onMeasure12+

onMeasure(constraint: LayoutConstraint): void

FrameNode的自定义测量方法,该方法会重写默认测量方法,在FrameNode进行测量时被调用,测量FrameNode及其内容的大小。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
constraint LayoutConstraint 组件进行测量时使用的布局约束。

示例:

请参考节点自定义示例

LayoutConstraint12+

描述组件的布局约束。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

名称 类型 必填 说明
maxSize Size 最大尺寸。
minSize Size 最小尺寸。
percentReference Size 子节点计算百分比时的尺寸基准。

onLayout12+

onLayout(position: Position): void

FrameNode的自定义布局方法,该方法会重写默认布局方法,在FrameNode进行布局时被调用,为FrameNode及其子节点指定位置。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
position Position 组件进行布局时使用的位置信息。

示例:

请参考节点自定义示例

setMeasuredSize12+

setMeasuredSize(size: Size): void

设置FrameNode的测量后的尺寸,默认单位PX。若设置的宽高为负数,自动取零。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
size Size FrameNode的测量后的尺寸。

示例:

请参考节点自定义示例

setLayoutPosition12+

setLayoutPosition(position: Position): void

设置FrameNode的布局后的位置,默认单位PX。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
position Position FrameNode的布局后的位置。

示例:

请参考节点自定义示例

measure12+

measure(constraint: LayoutConstraint): void

调用FrameNode的测量方法,根据父容器的布局约束,对FrameNode进行测量,计算出尺寸,如果测量方法被重写,则调用重写的方法。建议在onMeasure方法中调用。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
constraint LayoutConstraint 组件进行测量时使用的父容器布局约束。

示例:

请参考节点自定义示例

layout12+

layout(position: Position): void

调用FrameNode的布局方法,为FrameNode及其子节点指定布局位置,如果布局方法被重写,则调用重写的方法。建议在onLayout方法中调用。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
position Position 组件进行布局时使用的位置信息。

示例:

请参考节点自定义示例

setNeedsLayout12+

setNeedsLayout(): void

该方法会将FrameNode标记为需要布局的状态,下一帧将会进行重新布局。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

示例:

请参考节点自定义示例

invalidate12+

invalidate(): void

该方法会触发FrameNode自绘制内容的重新渲染。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

addComponentContent12+

addComponentContent<T>(content: ComponentContent<T>): void

支持添加ComponentContent类型的组件内容。要求当前节点是一个可修改的节点,即isModifiable的返回值为true,否则抛出异常信息。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
content ComponentContent<T> FrameNode节点中显示的组件内容。

错误码:

错误码ID 错误信息
100021 The FrameNode is not modifiable.
import { NodeController, FrameNode, ComponentContent, typeNode } from '@kit.ArkUI';

@Builder
function buildText() {
  Column() {
    Text('hello')
      .width(50)
      .height(50)
      .backgroundColor(Color.Yellow)
  }
}

class MyNodeController extends NodeController {
  makeNode(uiContext: UIContext): FrameNode | null {
    let node = new FrameNode(uiContext)
    node.commonAttribute.width(300).height(300).backgroundColor(Color.Red)
    let col = typeNode.createNode(uiContext, "Column")
    col.initialize({ space: 10 })
    node.appendChild(col)
    let row4 = typeNode.createNode(uiContext, "Row")
    row4.attribute.width(200)
      .height(200)
      .borderWidth(1)
      .borderColor(Color.Black)
      .backgroundColor(Color.Green)
    let component = new ComponentContent<Object>(uiContext, wrapBuilder(buildText))
    if (row4.isModifiable()) {
      row4.addComponentContent(component)
      col.appendChild(row4)
    }
    return node
  }
}

@Entry
@Component
struct FrameNodeTypeTest {
  private myNodeController: MyNodeController = new MyNodeController();

  build() {
    Row() {
      NodeContainer(this.myNodeController);
    }
  }
}

disposeTree12+

disposeTree(): void

下树并递归释放当前节点为根的子树。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

import { FrameNode, NodeController, BuilderNode } from '@kit.ArkUI';

@Component
struct TestComponent {
  private myNodeController: MyNodeController = new MyNodeController(wrapBuilder(buildComponent2));

  build() {
    Column() {
      Text('This is a BuilderNode.')
        .fontSize(16)
        .fontWeight(FontWeight.Bold)
      NodeContainer(this.myNodeController)
    }
    .width('100%')
    .backgroundColor(Color.Gray)
  }

  aboutToAppear() {
    console.error('BuilderNode aboutToAppear');
  }

  aboutToDisappear() {
    console.error('BuilderNode aboutToDisappear');
  }
}

@Component
struct TestComponent2 {
  private myNodeController: MyNodeController = new MyNodeController(wrapBuilder(buildComponent3));
  private myNodeController2: MyNodeController = new MyNodeController(wrapBuilder(buildComponent4));

  build() {
    Column() {
      Text('This is a BuilderNode 2.')
        .fontSize(16)
        .fontWeight(FontWeight.Bold)
      NodeContainer(this.myNodeController)
      NodeContainer(this.myNodeController2)
    }
    .width('100%')
    .backgroundColor(Color.Gray)
  }

  aboutToAppear() {
    console.error('BuilderNode 2 aboutToAppear');
  }

  aboutToDisappear() {
    console.error('BuilderNode 2 aboutToDisappear');
  }
}

@Component
struct TestComponent3 {
  build() {
    Column() {
      Text('This is a BuilderNode 3.')
        .fontSize(16)
        .fontWeight(FontWeight.Bold)

    }
    .width('100%')
    .backgroundColor(Color.Gray)
  }

  aboutToAppear() {
    console.error('BuilderNode 3 aboutToAppear');
  }

  aboutToDisappear() {
    console.error('BuilderNode 3 aboutToDisappear');
  }
}

@Component
struct TestComponent4 {
  build() {
    Column() {
      Text('This is a BuilderNode 4.')
        .fontSize(16)
        .fontWeight(FontWeight.Bold)

    }
    .width('100%')
    .backgroundColor(Color.Gray)
  }

  aboutToAppear() {
    console.error('BuilderNode 4 aboutToAppear');
  }

  aboutToDisappear() {
    console.error('BuilderNode 4 aboutToDisappear');
  }
}

@Builder
function buildComponent() {
  TestComponent()
}

@Builder
function buildComponent2() {
  TestComponent2()
}

@Builder
function buildComponent3() {
  TestComponent3()
}

@Builder
function buildComponent4() {
  TestComponent4()
}

class MyNodeController extends NodeController {
  private rootNode: FrameNode | null = null;
  private builderNode: BuilderNode<[]> | null = null;
  private wrappedBuilder: WrappedBuilder<[]>;

  constructor(builder: WrappedBuilder<[]>) {
    super();
    this.wrappedBuilder = builder;
  }

  makeNode(uiContext: UIContext): FrameNode | null {
    this.builderNode = new BuilderNode(uiContext, { selfIdealSize: { width: 200, height: 100 } });
    this.builderNode.build(this.wrappedBuilder);

    return this.builderNode.getFrameNode();
  }

  dispose() {
    if (this.builderNode !== null) {
      this.builderNode.getFrameNode()?.disposeTree()
    }
  }

  removeBuilderNode() {
    const rootRenderNode = this.rootNode!.getRenderNode();
    if (rootRenderNode !== null && this.builderNode !== null && this.builderNode.getFrameNode() !== null) {
      rootRenderNode.removeChild(this.builderNode!.getFrameNode()!.getRenderNode());
    }
  }
}

@Entry
@Component
struct Index {
  private myNodeController: MyNodeController = new MyNodeController(wrapBuilder(buildComponent));

  build() {
    Column({ space: 4 }) {
      NodeContainer(this.myNodeController)
      Button('BuilderNode dispose')
        .onClick(() => {
          this.myNodeController.dispose();
        })
        .width('100%')
      Button('BuilderNode rebuild')
        .onClick(() => {
          this.myNodeController.rebuild();
        })
        .width('100%')
    }
  }
}

示例:

请参考节点自定义示例

setCrossLanguageOptions15+

setCrossLanguageOptions(options: CrossLanguageOptions): void

设置当前FrameNode的跨ArkTS语言访问选项。例如ArkTS语言创建的节点,设置该节点是否可通过非ArkTS语言进行属性设置。当前FrameNode如果不可修改或不可设置跨ArkTS语言访问选项,抛出异常信息。

说明:

当前仅支持Scroll类型的TypedFrameNode设置跨ArkTS语言访问选项。

原子化服务API: 从API version 15开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
options CrossLanguageOptions 跨ArkTS语言访问选项。

错误码:

错误码ID 错误信息
100022 The FrameNode cannot be set whether to support cross-language common attribute setting.

示例:

请参考节点操作示例

getCrossLanguageOptions15+

getCrossLanguageOptions(): CrossLanguageOptions

获取当前FrameNode的跨ArkTS语言访问选项。例如ArkTS语言创建的节点,返回该节点是否可通过非ArkTS语言进行属性设置。

原子化服务API: 从API version 15开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
CrossLanguageOptions 跨ArkTS语言访问选项。

示例:

请参考节点操作示例

recycle18+

recycle(): void

全局复用场景下,触发子组件回收,彻底释放FrameNode后端资源,以便于资源的重新复用,确保后端资源能够被有效回收并再次使用。

原子化服务API: 从API version 18开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

示例:

请参考节点复用回收使用示例

reuse18+

reuse(): void

全局复用场景下,触发子组件复用,实现FrameNode后端资源的复用,提升资源利用效率。为保证资源充足,可以在recycle之后使用。

原子化服务API: 从API version 18开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

示例:

请参考节点复用回收使用示例

TypedFrameNode12+

TypedFrameNode继承自FrameNode,用于声明具体类型的FrameNode。

属性

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

名称 类型 只读 可选 说明
initialize C 该接口用于创建对应组件的构造参数,用于设置/更新组件的初始值。
attribute T 该接口用于获取对应组件的属性设置对象,用于设置/更新组件的通用、私有属性。

说明:

commonAttribute仅在CustomFrameNode上生效,TypedFrameNode上commonAttribute行为未定义。建议使用attribute接口而非commonAttribute接口进行通用属性设置,如node.attribute.backgroundColor(Color.Pink)。

typeNode12+

typeNode提供创建具体类型的FrameNode能力,可通过FrameNode的基础接口进行自定义的挂载,使用占位容器进行显示。

使用typeNode创建Text、Image、Select、Toggle节点时,当传入的UIContext对应的UI实例销毁后,调用该接口会返回一个无效的FrameNode节点,无法正常挂载和显示。

示例:

请参考自定义具体类型节点示例

Text12+

type Text = TypedFrameNode<TextInterface, TextAttribute>

Text类型的FrameNode节点类型。不允许添加子组件。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<TextInterface, TextAttribute> 提供Text类型FrameNode节点。
说明:
TextInterface用于TypedFrameNodeinitialize接口的入参,入参为Text组件的构造函数类型。
TextAttribute用于TypedFrameNode的attribute接口的返回值,返回Text组件的属性设置对象。

createNode('Text')12+

createNode(context: UIContext, nodeType: 'Text'): Text

创建Text类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'Text' 创建Text类型的FrameNode节点。

返回值:

类型 说明
Text Text类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'Text');

Column12+

type Column = TypedFrameNode<ColumnInterface, ColumnAttribute>

Column类型的FrameNode节点类型。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<ColumnInterface, ColumnAttribute> 提供Column类型FrameNode节点。
说明:
ColumnInterface用于TypedFrameNodeinitialize接口的入参,入参为Column组件的构造函数类型。
ColumnAttribute用于TypedFrameNode的attribute接口的返回值,返回Column组件的属性设置对象。

createNode('Column')12+

createNode(context: UIContext, nodeType: 'Column'): Column

创建Column类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'Column' 创建Column类型的FrameNode节点。

返回值:

类型 说明
Column Column类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'Column');

Row12+

type Row = TypedFrameNode<RowInterface, RowAttribute>

Row类型的FrameNode节点类型。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<RowInterface, RowAttribute> 提供Row类型FrameNode节点。
说明:
RowInterface用于TypedFrameNodeinitialize接口的入参,入参为Row组件的构造函数类型。
RowAttribute用于TypedFrameNode的attribute接口的返回值,返回Row组件的属性设置对象。

createNode('Row')12+

createNode(context: UIContext, nodeType: 'Row'): Row

创建Row类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'Row' 创建Row类型的FrameNode节点。

返回值:

类型 说明
Row Row类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'Row');

Stack12+

type Stack = TypedFrameNode<StackInterface, StackAttribute>

Stack类型的FrameNode节点类型。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<StackInterface, StackAttribute> 提供Stack类型FrameNode节点。
说明:
StackInterface用于TypedFrameNodeinitialize接口的入参,入参为Stack组件的构造函数类型。
StackAttribute用于TypedFrameNode的attribute接口的返回值,返回Stack组件的属性设置对象。

createNode('Stack')12+

createNode(context: UIContext, nodeType: 'Stack'): Stack

创建Stack类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'Stack' 创建Stack类型的FrameNode节点。

返回值:

类型 说明
Stack Stack类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'Stack');

GridRow12+

type GridRow = TypedFrameNode<GridRowInterface, GridRowAttribute>

GridRow类型的FrameNode节点类型。只允许添加GridCol类型子组件。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<GridRowInterface, GridRowAttribute> 提供GridRow类型FrameNode节点。
说明:
GridRowInterface用于TypedFrameNodeinitialize接口的入参,入参为GridRow组件的构造函数类型。
GridRowAttribute用于TypedFrameNode的attribute接口的返回值,返回GridRow组件的属性设置对象。

createNode('GridRow')12+

createNode(context: UIContext, nodeType: 'GridRow'): GridRow

创建GridRow类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'GridRow' 创建GridRow类型的FrameNode节点。

返回值:

类型 说明
GridRow GridRow类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'GridRow');

GridCol12+

type GridCol = TypedFrameNode<GridColInterface, GridColAttribute>

GridCol类型的FrameNode节点类型。不允许添加子组件。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<GridColInterface, GridColAttribute> 提供GridCol类型FrameNode节点。
说明:
GridColInterface用于TypedFrameNodeinitialize接口的入参,入参为GridCol组件的构造函数类型。
GridColAttribute用于TypedFrameNode的attribute接口的返回值,返回GridCol组件的属性设置对象。

createNode('GridCol')12+

createNode(context: UIContext, nodeType: 'GridCol'): GridCol

创建GridCol类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'GridCol' 创建GridCol类型的FrameNode节点。

返回值:

类型 说明
GridCol GridCol类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'GridCol');

Flex12+

type Flex = TypedFrameNode<FlexInterface, FlexAttribute>

Flex类型的FrameNode节点类型。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<FlexInterface, FlexAttribute> 提供Flex类型FrameNode节点。
说明:
FlexInterface用于TypedFrameNodeinitialize接口的入参,入参为Flex组件的构造函数类型。
FlexAttribute用于TypedFrameNode的attribute接口的返回值,返回Flex组件的属性设置对象。

createNode('Flex')12+

createNode(context: UIContext, nodeType: 'Flex'): Flex

创建Flex类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'Flex' 创建Flex类型的FrameNode节点。

返回值:

类型 说明
Flex Flex类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'Flex');

Swiper12+

type Swiper = TypedFrameNode<SwiperInterface, SwiperAttribute>

Swiper类型的FrameNode节点类型。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<SwiperInterface, SwiperAttribute> 提供Swiper类型FrameNode节点。
说明:
SwiperInterface用于TypedFrameNodeinitialize接口的入参,入参为Swiper组件的构造函数类型。
SwiperAttribute用于TypedFrameNode的attribute接口的返回值,返回Swiper组件的属性设置对象。

createNode('Swiper')12+

createNode(context: UIContext, nodeType: 'Swiper'): Swiper

创建Swiper类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'Swiper' 创建Swiper类型的FrameNode节点。

返回值:

类型 说明
Swiper Swiper类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'Swiper');

Progress12+

type Progress = TypedFrameNode<ProgressInterface, ProgressAttribute>

Progress类型的FrameNode节点类型。不允许添加子组件。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<ProgressInterface, ProgressAttribute> 提供Progress类型FrameNode节点。
说明:
ProgressInterface用于TypedFrameNodeinitialize接口的入参,入参为Progress组件的构造函数类型。
ProgressAttribute用于TypedFrameNode的attribute接口的返回值,返回Progress组件的属性设置对象。

createNode('Progress')12+

createNode(context: UIContext, nodeType: 'Progress'): Progress

创建Progress类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'Progress' 创建Progress类型的FrameNode节点。

返回值:

类型 说明
Progress Progress类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'Progress');

Scroll12+

type Scroll = TypedFrameNode<ScrollInterface, ScrollAttribute>

Scroll类型的FrameNode节点类型。允许添加一个子组件。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<ScrollInterface, ScrollAttribute> 提供Scroll类型FrameNode节点。
说明:
ScrollInterface用于TypedFrameNodeinitialize接口的入参,入参为Scroll组件的构造函数类型。
ScrollAttribute用于TypedFrameNode的attribute接口的返回值,返回Scroll组件的属性设置对象。

createNode('Scroll')12+

createNode(context: UIContext, nodeType: 'Scroll'): Scroll

创建Scroll类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'Scroll' 创建Scroll类型的FrameNode节点。

返回值:

类型 说明
Scroll Scroll类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'Scroll');

getAttribute('Scroll')15+

getAttribute(node: FrameNode, nodeType: 'Scroll'): ScrollAttribute | undefined

获取Scroll节点的属性。若该节点非ArkTS语言创建,则需要设置是否支持跨语言访问,如果不支持跨语言访问,则返回undefined。该接口不支持声明式方式创建的节点。

原子化服务API: 从API version 15开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
node FrameNode 获取属性时所需的目标节点。
nodeType 'Scroll' 获取Scroll节点类型的属性。

返回值:

类型 说明
ScrollAttribute | undefined Scroll节点类型的属性,若获取失败,则返回undefined。

示例:

typeNode.getAttribute(node, 'Scroll');

bindController('Scroll')15+

bindController(node: FrameNode, controller: Scroller, nodeType: 'Scroll'): void

将滚动控制器Scroller绑定到Scroll节点。若该节点非ArkTS语言创建,则需要设置是否支持跨语言访问,如果不支持跨语言访问,则抛出异常。该接口不支持声明式方式创建的节点。

原子化服务API: 从API version 15开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
node FrameNode 绑定滚动控制器的目标节点。
controller Scroller 滚动控制器。
nodeType 'Scroll' 绑定滚动控制器的目标节点的节点类型为Scroll。

错误码:

错误码ID 错误信息
401 Parameter error. Possible causes: 1. the type of the node is error. 2. the node is null or undefined.
100021 The FrameNode is not modifiable.

示例:

typeNode.bindController(node, scroller, 'Scroll');

RelativeContainer12+

type RelativeContainer = TypedFrameNode<RelativeContainerInterface, RelativeContainerAttribute>

RelativeContainer类型的FrameNode节点类型。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<RelativeContainerInterface, RelativeContainerAttribute> 提供RelativeContainer类型FrameNode节点。
说明:
RelativeContainerInterface用于TypedFrameNodeinitialize接口的入参,入参为RelativeContainer组件的构造函数类型。
RelativeContainerAttribute用于TypedFrameNode的attribute接口的返回值,返回RelativeContainer组件的属性设置对象。

createNode('RelativeContainer')12+

createNode(context: UIContext, nodeType: 'RelativeContainer'): RelativeContainer

创建RelativeContainer类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'RelativeContainer' 创建RelativeContainer类型的FrameNode节点。

返回值:

类型 说明
RelativeContainer RelativeContainer类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'RelativeContainer');

Divider12+

type Divider = TypedFrameNode<DividerInterface, DividerAttribute>

Divider类型的FrameNode节点类型。不允许添加子组件。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<DividerInterface, DividerAttribute> 提供Divider类型FrameNode节点。
说明:
DividerInterface用于TypedFrameNodeinitialize接口的入参,入参为RelativeContainer组件的构造函数类型。
DividerAttribute用于TypedFrameNode的attribute接口的返回值,返回Divider组件的属性设置对象。

createNode('Divider')12+

createNode(context: UIContext, nodeType: 'Divider'): Divider

创建Divider类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'Divider' 创建Divider类型的FrameNode节点。

返回值:

类型 说明
Divider Divider类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'Divider');

LoadingProgress12+

type LoadingProgress = TypedFrameNode<LoadingProgressInterface, LoadingProgressAttribute>

LoadingProgress类型的FrameNode节点类型。不允许添加子组件。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<LoadingProgressInterface, LoadingProgressAttribute> 提供LoadingProgress类型FrameNode节点。
说明:
LoadingProgressInterface用于TypedFrameNodeinitialize接口的入参,入参为LoadingProgress组件的构造函数类型。
LoadingProgressAttribute用于TypedFrameNode的attribute接口的返回值,返回LoadingProgress组件的属性设置对象。

createNode('LoadingProgress')12+

createNode(context: UIContext, nodeType: 'LoadingProgress'): LoadingProgress

创建LoadingProgress类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'LoadingProgress' 创建LoadingProgress类型的FrameNode节点。

返回值:

类型 说明
LoadingProgress LoadingProgress类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'LoadingProgress');

Search12+

type Search = TypedFrameNode<SearchInterface, SearchAttribute>

Search类型的FrameNode节点类型。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<SearchInterface, SearchAttribute> 提供Search类型FrameNode节点。
说明:
SearchInterface用于TypedFrameNodeinitialize接口的入参,入参为Search组件的构造函数类型。
SearchAttribute用于TypedFrameNode的attribute接口的返回值,返回Search组件的属性设置对象。

createNode('Search')12+

createNode(context: UIContext, nodeType: 'Search'): Search

创建Search类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'Search' 创建Search类型的FrameNode节点。

返回值:

类型 说明
Search Search类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'Search');

Blank12+

type Blank = TypedFrameNode<BlankInterface, BlankAttribute>

Blank类型的FrameNode节点类型。不允许添加子组件。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<BlankInterface, BlankAttribute> 提供Blank类型FrameNode节点。
说明:
BlankInterface用于TypedFrameNodeinitialize接口的入参,入参为Blank组件的构造函数类型。
BlankAttribute用于TypedFrameNode的attribute接口的返回值,返回Blank组件的属性设置对象。

createNode('Blank')12+

createNode(context: UIContext, nodeType: 'Blank'): Blank

创建Blank类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'Blank' 创建Blank类型的FrameNode节点。

返回值:

类型 说明
Blank Blank类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'Blank');

Image12+

type Image = TypedFrameNode<ImageInterface, ImageAttribute>

Image类型的FrameNode节点类型。不允许添加子组件。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<ImageInterface, ImageAttribute> 提供Image类型FrameNode节点。
说明:
ImageInterface用于TypedFrameNodeinitialize接口的入参,入参为Image组件的构造函数类型。
ImageAttribute用于TypedFrameNode的attribute接口的返回值,返回Image组件的属性设置对象。

createNode('Image')12+

createNode(context: UIContext, nodeType: 'Image'): Image

创建Image类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'Image' 创建Image类型的节点。

返回值:

类型 说明
Image Image类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'Image');

List12+

type List = TypedFrameNode<ListInterface, ListAttribute>

List类型的FrameNode节点类型。只允许添加ListItem、ListItemGroup类型子组件。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<ListInterface, ListAttribute> 提供List类型FrameNode节点。
说明:
ListInterface用于TypedFrameNodeinitialize接口的入参,入参为List组件的构造函数类型。
ListAttribute用于TypedFrameNode的attribute接口的返回值,返回List组件的属性设置对象。

createNode('List')12+

createNode(context: UIContext, nodeType: 'List'): List

创建List类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'List' 创建List类型的节点。

返回值:

类型 说明
List List类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'List');

ListItem12+

type ListItem = TypedFrameNode<ListItemInterface, ListItemAttribute>

ListItem类型的FrameNode节点类型。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<ListItemInterface, ListItemAttribute> 提供ListItem类型FrameNode节点。
说明:
ListItemInterface用于TypedFrameNodeinitialize接口的入参,入参为ListItem组件的构造函数类型。
ListItemAttribute用于TypedFrameNode的attribute接口的返回值,返回ListItem组件的属性设置对象。

createNode('ListItem')12+

createNode(context: UIContext, nodeType: 'ListItem'): ListItem

创建ListItem类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'ListItem' 创建ListItem类型的节点。

返回值:

类型 说明
ListItem ListItem类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'ListItem');

TextInput12+

type TextInput = TypedFrameNode<TextInputInterface, TextInputAttribute>

TextInput类型的FrameNode节点类型。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<TextInputInterface, TextInputAttribute> 提供TextInput类型FrameNode节点。
说明:
TextInputInterface用于TypedFrameNodeinitialize接口的入参,入参为TextInput组件的构造函数类型。
TextInputAttribute用于TypedFrameNode的attribute接口的返回值,返回TextInput组件的属性设置对象。

createNode('TextInput')12+

createNode(context: UIContext, nodeType: 'TextInput'): TextInput

创建TextInput类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'TextInput' 创建TextInput类型的节点。

返回值:

类型 说明
TextInput TextInput类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'TextInput');

Button12+

type Button = TypedFrameNode<ButtonInterface, ButtonAttribute>

Button类型的FrameNode节点类型。以子组件模式创建允许添加一个子组件。以label模式创建不可以添加子组件。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<ButtonInterface, ButtonAttribute> 提供Button类型FrameNode节点。
说明:
ButtonInterface用于TypedFrameNodeinitialize接口的入参,入参为Button组件的构造函数类型。
ButtonAttribute用于TypedFrameNode的attribute接口的返回值,返回Button组件的属性设置对象。
接口入参label不为空时,以label模式创建Button组件,以此模式创建无法包含子组件,并且不允许再设置子组件,否则会抛出异常。且label模式和子组件模式在第一次initialize创建之后无法在后续的initialize进行动态修改,如需要包含子组件,第一次initialize时不要设置label参数。
以子组件模式创建时,只能包含一个子组件,不能设置多个子组件,否则会抛出异常。

createNode('Button')12+

createNode(context: UIContext, nodeType: 'Button'): Button

创建Button类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'Button' 创建Button类型的节点。

返回值:

类型 说明
Button Button类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'Button');

ListItemGroup12+

type ListItemGroup = TypedFrameNode<ListItemGroupInterface, ListItemGroupAttribute>

ListItemGroup类型的FrameNode节点类型。只允许添加ListItem类型子组件。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<ListItemGroupInterface, ListItemGroupAttribute> 提供ListItemGroup类型FrameNode节点。
说明:
ListItemGroupInterface用于TypedFrameNodeinitialize接口的入参,入参为ListItemGroup组件的构造函数类型。
ListItemGroupAttribute用于TypedFrameNode的attribute接口的返回值,返回ListItemGroup组件的属性设置对象。

createNode('ListItemGroup')12+

createNode(context: UIContext, nodeType: 'ListItemGroup'): ListItemGroup

创建ListItemGroup类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'ListItemGroup' 创建ListItemGroup类型的节点。

返回值:

类型 说明
ListItemGroup ListItemGroup类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'ListItemGroup');

WaterFlow12+

type WaterFlow = TypedFrameNode<WaterFlowInterface, WaterFlowAttribute>

WaterFlow类型的FrameNode节点类型。只允许添加FlowItem类型子组件。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<WaterFlowInterface, WaterFlowAttribute> 提供WaterFlow类型FrameNode节点。
说明:
WaterFlowInterface用于TypedFrameNodeinitialize接口的入参,入参为WaterFlow组件的构造函数类型。
WaterFlowAttribute用于TypedFrameNode的attribute接口的返回值,返回WaterFlow组件的属性设置对象。

createNode('WaterFlow')12+

createNode(context: UIContext, nodeType: 'WaterFlow'): WaterFlow

创建WaterFlow类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'WaterFlow' 创建WaterFlow类型的节点。

返回值:

类型 说明
WaterFlow WaterFlow类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'WaterFlow');

FlowItem12+

type FlowItem = TypedFrameNode<FlowItemInterface, FlowItemAttribute>

FlowItem类型的FrameNode节点类型。允许添加一个子组件。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<FlowItemInterface, FlowItemAttribute> 提供FlowItem类型FrameNode节点。
说明:
FlowItemInterface用于TypedFrameNodeinitialize接口的入参,入参为FlowItem组件的构造函数类型。
FlowItemAttribute用于TypedFrameNode的attribute接口的返回值,返回FlowItem组件的属性设置对象。

createNode('FlowItem')12+

createNode(context: UIContext, nodeType: 'FlowItem'): FlowItem

创建FlowItem类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'FlowItem' 创建FlowItem类型的节点。

返回值:

类型 说明
FlowItem FlowItem类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'FlowItem');

XComponent12+

type XComponent = TypedFrameNode<XComponentInterface, XComponentAttribute>

XComponent类型的FrameNode节点类型。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<XComponentInterface, XComponentAttribute> 提供XComponent类型FrameNode节点。
说明:
XComponentInterface用于TypedFrameNodeinitialize接口的入参,入参为XComponent组件的构造函数类型。
XComponentAttribute用于TypedFrameNode的attribute接口的返回值,返回XComponent组件的属性设置对象。

createNode('XComponent')12+

createNode(context: UIContext, nodeType: 'XComponent'): XComponent

创建XComponent类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'XComponent' 创建XComponent类型的节点。

返回值:

类型 说明
XComponent XComponent类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'XComponent');

createNode('XComponent')12+

createNode(context: UIContext, nodeType: 'XComponent', options: XComponentOptions): XComponent

按照options中的配置参数创建XComponent类型的FrameNode节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'XComponent' 创建XComponent类型的节点。
options XComponentOptions 定义XComponent的具体配置参数。

返回值:

类型 说明
XComponent XComponent类型的FrameNode节点。

示例:

let controller: XComponentController = new XComponentController();
let options: XComponentOptions = {
  type: XComponentType.TEXTURE,
  controller: controller
};
typeNode.createNode(uiContext, 'XComponent', options);

QRCode14+

type QRCode = TypedFrameNode<QRCodeInterface, QRCodeAttribute>

QRCode类型的FrameNode节点类型。

原子化服务API: 从API version 14开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<QRCodeInterface, QRCodeAttribute> 提供QRCode类型FrameNode节点。
说明:
QRCodeInterface用于TypedFrameNodeinitialize接口的入参,入参为QRCode组件的构造函数类型。
QRCodeAttribute用于TypedFrameNode的attribute接口的返回值,返回QRCode组件的属性设置对象。

createNode('QRCode')14+

createNode(context: UIContext, nodeType: 'QRCode'): QRCode

创建QRCode类型的FrameNode节点。

原子化服务API: 从API version 14开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'QRCode' 创建QRCode类型的节点。

返回值:

类型 说明
QRCode QRCode类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'QRCode');

Badge14+

type Badge = TypedFrameNode<BadgeInterface, BadgeAttribute>

Badge类型的FrameNode节点类型。

原子化服务API: 从API version 14开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<BadgeInterface, BadgeAttribute> 提供Badge类型FrameNode节点。
说明:
BadgeInterface用于TypedFrameNodeinitialize接口的入参,入参为Badge组件的构造函数类型。
BadgeAttribute用于TypedFrameNode的attribute接口的返回值,返回Badge组件的属性设置对象。

createNode('Badge')14+

createNode(context: UIContext, nodeType: 'Badge'): Badge

创建Badge类型的FrameNode节点。

原子化服务API: 从API version 14开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'Badge' 创建Badge类型的节点。

返回值:

类型 说明
Badge Badge类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'Badge');

Grid14+

type Grid = TypedFrameNode<GridInterface, GridAttribute>

Grid类型的FrameNode节点类型。

原子化服务API: 从API version 14开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<GridInterface, GridAttribute> 提供Grid类型FrameNode节点。
说明:
GridInterface用于TypedFrameNodeinitialize接口的入参,入参为Grid组件的构造函数类型。
GridAttribute用于TypedFrameNode的attribute接口的返回值,返回Grid组件的属性设置对象。

createNode('Grid')14+

createNode(context: UIContext, nodeType: 'Grid'): Grid

创建Grid类型的FrameNode节点。

原子化服务API: 从API version 14开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'Grid' 创建Grid类型的节点。

返回值:

类型 说明
Grid Grid类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'Grid');

GridItem14+

type GridItem = TypedFrameNode<GridItemInterface, GridItemAttribute>

GridItem类型的FrameNode节点类型。

原子化服务API: 从API version 14开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<GridItemInterface, GridItemAttribute> 提供GridItem类型FrameNode节点。
说明:
GridItemInterface用于TypedFrameNodeinitialize接口的入参,入参为GridItem组件的构造函数类型。
GridItemAttribute用于TypedFrameNode的attribute接口的返回值,返回GridItem组件的属性设置对象。

createNode('GridItem')14+

createNode(context: UIContext, nodeType: 'GridItem'): GridItem

创建GridItem类型的FrameNode节点。

原子化服务API: 从API version 14开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'GridItem' 创建GridItem类型的节点。

返回值:

类型 说明
GridItem GridItem类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'GridItem');

TextClock14+

type TextClock = TypedFrameNode<TextClockInterface, TextClockAttribute>

TextClock类型的FrameNode节点类型。

原子化服务API: 从API version 14开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<TextClockInterface, TextClockAttribute> 提供TextClock类型FrameNode节点。
说明:
TextClockInterface用于TypedFrameNodeinitialize接口的入参,入参为TextClock组件的构造函数类型。
TextClockAttribute用于TypedFrameNode的attribute接口的返回值,返回TextClock组件的属性设置对象。

createNode('TextClock')14+

createNode(context: UIContext, nodeType: 'TextClock'): TextClock

创建TextClock类型的FrameNode节点。

原子化服务API: 从API version 14开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'TextClock' 创建TextClock类型的节点。

返回值:

类型 说明
TextClock TextClock类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'TextClock');

TextTimer14+

type TextTimer = TypedFrameNode<TextTimerInterface, TextTimerAttribute>

TextTimer类型的FrameNode节点类型。

原子化服务API: 从API version 14开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<TextTimerInterface, TextTimerAttribute> 提供TextTimer类型FrameNode节点。
说明:
TextTimerInterface用于TypedFrameNodeinitialize接口的入参,入参为TextTimer组件的构造函数类型。
TextTimerAttribute用于TypedFrameNode的attribute接口的返回值,返回TextTimer组件的属性设置对象。

createNode('TextTimer')14+

createNode(context: UIContext, nodeType: 'TextTimer'): TextTimer

创建TextTimer类型的FrameNode节点。

原子化服务API: 从API version 14开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'TextTimer' 创建TextTimer类型的节点。

返回值:

类型 说明
TextTimer TextTimer类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'TextTimer');

Marquee14+

type Marquee = TypedFrameNode<MarqueeInterface, MarqueeAttribute>

Marquee类型的FrameNode节点类型。

原子化服务API: 从API version 14开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<MarqueeInterface, MarqueeAttribute> 提供Marquee类型FrameNode节点。
说明:
MarqueeInterface用于TypedFrameNodeinitialize接口的入参,入参为Marquee组件的构造函数类型。
MarqueeAttribute用于TypedFrameNode的attribute接口的返回值,返回Marquee组件的属性设置对象。

createNode('Marquee')14+

createNode(context: UIContext, nodeType: 'Marquee'): Marquee

创建Marquee类型的FrameNode节点。

原子化服务API: 从API version 14开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'Marquee' 创建Marquee类型的节点。

返回值:

类型 说明
Marquee Marquee类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'Marquee');

TextArea14+

type TextArea = TypedFrameNode<TextAreaInterface, TextAreaAttribute>

TextArea类型的FrameNode节点类型。

原子化服务API: 从API version 14开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<TextAreaInterface, TextAreaAttribute> 提供TextArea类型FrameNode节点。
说明:
TextAreaInterface用于TypedFrameNodeinitialize接口的入参,入参为TextArea组件的构造函数类型。
TextAreaAttribute用于TypedFrameNode的attribute接口的返回值,返回TextArea组件的属性设置对象。

createNode('TextArea')14+

createNode(context: UIContext, nodeType: 'TextArea'): TextArea

创建TextArea类型的FrameNode节点。

原子化服务API: 从API version 14开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'TextArea' 创建TextArea类型的节点。

返回值:

类型 说明
TextArea TextArea类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'TextArea');

SymbolGlyph14+

type SymbolGlyph = TypedFrameNode<SymbolGlyphInterface, SymbolGlyphAttribute>

SymbolGlyph类型的FrameNode节点类型。

原子化服务API: 从API version 14开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<SymbolGlyphInterface, SymbolGlyphAttribute> 提供SymbolGlyph类型FrameNode节点。
说明:
SymbolGlyphInterface用于TypedFrameNodeinitialize接口的入参,入参为SymbolGlyph组件的构造函数类型。
SymbolGlyphAttribute用于TypedFrameNode的attribute接口的返回值,返回SymbolGlyph组件的属性设置对象。

createNode('SymbolGlyph')14+

createNode(context: UIContext, nodeType: 'SymbolGlyph'): SymbolGlyph

创建SymbolGlyph类型的FrameNode节点。

原子化服务API: 从API version 14开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'SymbolGlyph' 创建SymbolGlyph类型的节点。

返回值:

类型 说明
SymbolGlyph SymbolGlyph类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'SymbolGlyph');

Checkbox18+

type Checkbox = TypedFrameNode<CheckboxInterface, CheckboxAttribute>

Checkbox类型的FrameNode节点类型。

原子化服务API: 从API version 18开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<CheckboxInterface, CheckboxAttribute> 提供Checkbox类型FrameNode节点。
说明:
CheckboxInterface用于TypedFrameNodeinitialize接口的入参,入参为Checkbox组件的构造函数类型。
CheckboxAttribute用于TypedFrameNode的attribute接口的返回值,返回Checkbox组件的属性设置对象。

createNode('Checkbox')18+

createNode(context: UIContext, nodeType: 'Checkbox'): Checkbox

创建Checkbox类型的FrameNode节点。

原子化服务API: 从API version 18开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'Checkbox' 创建Checkbox类型的节点。

返回值:

类型 说明
Checkbox Checkbox类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'Checkbox');

CheckboxGroup18+

type CheckboxGroup = TypedFrameNode<CheckboxGroupInterface, CheckboxGroupAttribute>

CheckboxGroup类型的FrameNode节点类型。

原子化服务API: 从API version 18开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<CheckboxGroupInterface, CheckboxGroupAttribute> 提供CheckboxGroup类型FrameNode节点。
说明:
CheckboxGroupInterface用于TypedFrameNodeinitialize接口的入参,入参为CheckboxGroup组件的构造函数类型。
CheckboxGroupAttribute用于TypedFrameNode的attribute接口的返回值,返回CheckboxGroup组件的属性设置对象。

createNode('CheckboxGroup')18+

createNode(context: UIContext, nodeType: 'CheckboxGroup'): CheckboxGroup

创建CheckboxGroup类型的FrameNode节点。

原子化服务API: 从API version 18开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'CheckboxGroup' 创建CheckboxGroup类型的节点。

返回值:

类型 说明
CheckboxGroup CheckboxGroup类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'CheckboxGroup');

Rating18+

type Rating = TypedFrameNode<RatingInterface, RatingAttribute>

Rating类型的FrameNode节点类型。

原子化服务API: 从API version 18开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<RatingInterface, RatingAttribute> 提供Rating类型FrameNode节点。
说明:
RatingInterface用于TypedFrameNodeinitialize接口的入参,入参为Rating组件的构造函数类型。
RatingAttribute用于TypedFrameNode的attribute接口的返回值,返回Rating组件的属性设置对象。

createNode('Rating')18+

createNode(context: UIContext, nodeType: 'Rating'): Rating

创建Rating类型的FrameNode节点。

原子化服务API: 从API version 18开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'Rating' 创建Rating类型的节点。

返回值:

类型 说明
Rating Rating类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'Rating');

Radio18+

type Radio = TypedFrameNode<RadioInterface, RadioAttribute>

Radio类型的FrameNode节点类型。

原子化服务API: 从API version 18开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<RadioInterface, RadioAttribute> 提供Radio类型FrameNode节点。
说明:
RadioInterface用于TypedFrameNodeinitialize接口的入参,入参为Radio组件的构造函数类型。
RadioAttribute用于TypedFrameNode的attribute接口的返回值,返回Radio组件的属性设置对象。

createNode('Radio')18+

createNode(context: UIContext, nodeType: 'Radio'): Radio

创建Radio类型的FrameNode节点。

原子化服务API: 从API version 18开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'Radio' 创建Radio类型的节点。

返回值:

类型 说明
Radio Radio类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'Radio');

Slider18+

type Slider = TypedFrameNode<SliderInterface, SliderAttribute>

Slider类型的FrameNode节点类型。

原子化服务API: 从API version 18开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<SliderInterface, SliderAttribute> 提供Slider类型FrameNode节点。
说明:
SliderInterface用于TypedFrameNodeinitialize接口的入参,入参为Slider组件的构造函数类型。
SliderAttribute用于TypedFrameNode的attribute接口的返回值,返回Slider组件的属性设置对象。

createNode('Slider')18+

createNode(context: UIContext, nodeType: 'Slider'): Slider

创建Slider类型的FrameNode节点。

原子化服务API: 从API version 18开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'Slider' 创建Slider类型的节点。

返回值:

类型 说明
Slider Slider类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'Slider');

Select18+

type Select = TypedFrameNode<SelectInterface, SelectAttribute>

Select类型的FrameNode节点类型。

原子化服务API: 从API version 18开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<SelectInterface, SelectAttribute> 提供Select类型FrameNode节点。
说明:
SelectInterface用于TypedFrameNodeinitialize接口的入参,入参为Select组件的构造函数类型。
SelectAttribute用于TypedFrameNode的attribute接口的返回值,返回Select组件的属性设置对象。

createNode('Select')18+

createNode(context: UIContext, nodeType: 'Select'): Select

创建Select类型的FrameNode节点。

原子化服务API: 从API version 18开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'Select' 创建Select类型的节点。

返回值:

类型 说明
Select Select类型的FrameNode节点。

示例:

typeNode.createNode(uiContext, 'Select');

Toggle18+

type Toggle = TypedFrameNode<ToggleInterface, ToggleAttribute>

Toggle类型的FrameNode节点类型。

原子化服务API: 从API version 18开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

类型 说明
TypedFrameNode<ToggleInterface, ToggleAttribute> 提供Toggle类型FrameNode节点。
说明:
ToggleInterface用于TypedFrameNodeinitialize接口的入参,入参为Toggle组件的构造函数类型。
ToggleAttribute用于TypedFrameNode的attribute接口的返回值,返回Toggle组件的属性设置对象。

createNode('Toggle')18+

createNode(context: UIContext, nodeType: 'Toggle', options?: ToggleOptions): Toggle

创建Toggle类型的FrameNode节点。

原子化服务API: 从API version 18开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
context UIContext 创建对应节点时所需的UI上下文。
nodeType 'Toggle' 创建Toggle类型的节点。
options ToggleOptions 创建Toggle节点的接口参数,仅可通过ToggleOptions中的type属性设置开关样式。

返回值:

类型 说明
Toggle Toggle类型的FrameNode节点。

示例:

let toggleOptions: ToggleOptions = {type: ToggleType.Button, isOn: false};
typeNode.createNode(uiContext, 'Toggle', toggleOptions);

NodeAdapter12+

NodeAdapter提供FrameNode的数据懒加载能力。

说明:

入参不能为负数,入参为负数时不做处理。

示例:

请参考NodeAdapter使用示例

constructor12+

constructor()

NodeAdapter的构造函数。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

dispose12+

dispose(): void

立即释放当前的NodeAdapter。如果是已绑定的状态,会先进行解绑操作,再释放当前的NodeAdapter。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

totalNodeCount12+

set totalNodeCount(count: number)

设置数据节点总数。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
count number 数据节点总数。
取值范围:[0, +∞)

get totalNodeCount(): number

获取数据节点总数。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
number 数据节点总数。
取值范围:[0, +∞)

reloadAllItems12+

reloadAllItems(): void

重新加载全部数据操作。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

reloadItem12+

reloadItem(start: number, count: number): void

从索引值开始重新加载指定数量的节点数据。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
start number 重新加载的节点开始索引值。
取值范围:[0, +∞)
count number 重新加载数据节点的数量。
取值范围:[0, +∞)

removeItem12+

removeItem(start: number, count: number): void

从索引值开始删除指定数量的节点数据。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
start number 删除的节点开始索引值。
取值范围:[0, +∞)
count number 删除数据节点的数量。
取值范围:[0, +∞)

insertItem12+

insertItem(start: number, count: number): void

从索引值开始新增指定数量的节点数据。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
start number 新增的节点开始索引值。
取值范围:[0, +∞)
count number 新增数据节点的数量。
取值范围:[0, +∞)

moveItem12+

moveItem(from: number, to: number): void

将数据从原始索引移动到目的索引。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
from number 数据移动的原始索引值。
取值范围:[0, +∞)
to number 数据移动的目的索引值。
取值范围:[0, +∞)

getAllAvailableItems12+

getAllAvailableItems(): Array<FrameNode>

获取所有有效数据。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

返回值:

类型 说明
Array<FrameNode> FrameNode数据节点集合。

onAttachToNode12+

onAttachToNode?(target: FrameNode): void

FrameNode绑定NodeAdapter时回调。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
target FrameNode 绑定NodeAdapter的FrameNode节点。

onDetachFromNode12+

onDetachFromNode?(): void

解除绑定时回调。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

onGetChildId12+

onGetChildId?(index: number): number

节点首次加载或新节点滑入时回调。用于生成自定义的Id,需要开发者自行保证Id的唯一性。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
index number 加载节点索引值。
取值范围:[0, +∞)

返回值:

类型 说明
number 返回开发者自定义生成的Id,需要开发者自行保证Id的唯一性。

onCreateChild12+

onCreateChild?(index: number): FrameNode

节点首次加载或新节点滑入时回调。建议开发者在添加子组件时,遵循声明式组件中子组件的约束。例如,WaterFlow支持添加FlowItem子节点。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
index number 加载节点索引值。
取值范围:[0, +∞)

返回值:

类型 说明
FrameNode 返回开发者创建的FrameNode节点。

onDisposeChild12+

onDisposeChild?(id: number, node: FrameNode): void

子节点即将销毁时回调。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
id number 即将销毁的子节点id。
node FrameNode 即将销毁的FrameNode节点。

onUpdateChild12+

onUpdateChild?(id: number, node: FrameNode): void

重新加载的数据节点被复用时回调。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
id number 复用节点索引值。
node FrameNode 被复用的FrameNode节点。

attachNodeAdapter12+

static attachNodeAdapter(adapter: NodeAdapter, node: FrameNode): boolean

给FrameNode绑定一个NodeAdapter。一个节点只能绑定一个NodeAdapter。已经绑定NodeAdapter的再次绑定会失败并返回false。

说明:

支持绑定的组件:Column、Row、Stack、GridRow、Flex、Swiper、RelativeContainer、List、ListItemGroup、WaterFlow、Grid。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
adapter NodeAdapter 定义懒加载的NodeAdapter类。
node FrameNode 绑定的FrameNode节点。

返回值:

类型 说明
boolean 绑定结果,返回true绑定成功,false绑定失败。

detachNodeAdapter12+

static detachNodeAdapter(node: FrameNode): void

解除绑定操作,解除FrameNode节点绑定的NodeAdapter。

原子化服务API: 从API version 12开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
node FrameNode 要解除绑定的FrameNode节点。

自定义具体类型节点示例

以Text节点为例,创建Text类型节点。

import { NodeController, FrameNode, typeNode } from '@kit.ArkUI';

class MyNodeController extends NodeController {
  makeNode(uiContext: UIContext): FrameNode | null {
    let node = new FrameNode(uiContext);
    node.commonAttribute.width(100)
      .height(50)
      .borderColor(Color.Gray)
      .borderWidth(1)
      .margin({ left: 10 });
    let col = typeNode.createNode(uiContext, 'Column');
    col.initialize({ space: 5 })
      .width('100%').height('100%').margin({ top: 5 });
    node.appendChild(col);
    let text = typeNode.createNode(uiContext, 'Text');
    text.initialize("Hello").fontColor(Color.Blue).fontSize(14);
    col.appendChild(text);
    return node;
  }
}

@Entry
@Component
struct FrameNodeTypeTest {
  private myNodeController: MyNodeController = new MyNodeController();

  build() {
    Row() {
      NodeContainer(this.myNodeController);
    }
  }
}

FrameNodeTextTest

节点操作示例

import { NodeController, FrameNode, UIContext, typeNode } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';

const TEST_TAG: string = "FrameNode "

class MyNodeController extends NodeController {
  public frameNode: FrameNode | null = null;
  public childList: Array<FrameNode> = new Array<FrameNode>();
  private rootNode: FrameNode | null = null;
  private uiContext: UIContext | null = null;
  private childrenCount: number = 0;

  makeNode(uiContext: UIContext): FrameNode | null {
    this.rootNode = new FrameNode(uiContext);
    this.uiContext = uiContext;

    this.frameNode = new FrameNode(uiContext);
    this.frameNode.commonAttribute.backgroundColor(Color.Pink);
    this.frameNode.commonAttribute.size({ width: 100, height: 100 });

    this.rootNode.appendChild(this.frameNode);
    this.childrenCount = this.childrenCount + 1;
    for (let i = 0; i < 10; i++) {
      let childNode = new FrameNode(uiContext);
      this.childList.push(childNode);
      this.frameNode.appendChild(childNode);
    }
    let stackNode = typeNode.createNode(uiContext, "Stack");
    this.frameNode.appendChild(stackNode);
    return this.rootNode;
  }

  createFrameNode() {
    let frameNode = new FrameNode(this.uiContext!);
    frameNode.commonAttribute.backgroundColor(Color.Pink);
    frameNode.commonAttribute.size({ width: 100, height: 100 });
    frameNode.commonAttribute.position({ x: this.childrenCount * 120, y: 0 });

    return frameNode;
  }

  appendChild() {
    const childNode = this.createFrameNode();
    this.rootNode!.appendChild(childNode);
    this.childrenCount = this.childrenCount + 1;
  }

  insertChildAfter(index: number) {
    let insertNode = this.createFrameNode();
    let childNode = this.rootNode!.getChild(index);
    this.rootNode!.insertChildAfter(insertNode, childNode);
    this.childrenCount = this.childrenCount + 1;
  }

  removeChild(index: number) {
    let childNode = this.rootNode!.getChild(index);
    if (childNode == null) {
      console.log(`${TEST_TAG} getchild at index {${index}} : fail`);
      return;
    }
    this.rootNode!.removeChild(childNode);
    this.childrenCount = this.childrenCount - 1;
  }

  getChildNumber() {
    console.log(TEST_TAG + " getChildNumber " + this.rootNode!.getChildrenCount())
    console.log(TEST_TAG + " children count is " + this.childrenCount);
  }

  clearChildren() {
    this.rootNode!.clearChildren();
  }

  searchFrameNode() {
    if (this.rootNode!.getFirstChild() === null) {
      console.log(TEST_TAG + " the rootNode does not have child node.")
    }
    if (this.rootNode!.getFirstChild() === this.frameNode) {
      console.log(TEST_TAG +
        " getFirstChild  result: success. The first child of the rootNode is equals to frameNode.");
    } else {
      console.log(TEST_TAG +
        " getFirstChild  result: fail. The first child of the rootNode is not equals to frameNode.");
    }
    if (this.frameNode!.getChild(5) === this.frameNode!.getChild(4)!.getNextSibling()) {
      console.log(TEST_TAG + " getNextSibling  result: success.");
    } else {
      console.log(TEST_TAG + " getNextSibling  result: fail.");
    }
    if (this.frameNode!.getChild(3) === this.frameNode!.getChild(4)!.getPreviousSibling()) {
      console.log(TEST_TAG + " getPreviousSibling  result: success.");
    } else {
      console.log(TEST_TAG + " getPreviousSibling  result: fail.");
    }
    if (this.rootNode!.getFirstChild() !== null && this.rootNode!.getFirstChild()!.getParent() === this.rootNode) {
      console.log(TEST_TAG + " getParent  result: success.");
    } else {
      console.log(TEST_TAG + " getParent  result: fail.");
    }
    if (this.rootNode!.getParent() !== undefined || this.rootNode!.getParent() !== null) {
      console.log(TEST_TAG + " get ArkTsNode success.")
      console.log(TEST_TAG + " check rootNode whether is modifiable " + this.rootNode!.isModifiable())
      console.log(TEST_TAG + " check getParent whether is modifiable " + this.rootNode!.getParent()!.isModifiable())
    } else {
      console.log(TEST_TAG + " get ArkTsNode fail.");
    }
  }

  moveFrameNode() {
    const currentNode = this.frameNode!.getChild(10);
    try {
      currentNode!.moveTo(this.rootNode, 0);
      if (this.rootNode!.getChild(0) === currentNode) {
        console.log(TEST_TAG + " moveTo  result: success.");
      } else {
        console.log(TEST_TAG + " moveTo  result: fail.");
      }
    } catch (err) {
      console.log(TEST_TAG + " " + (err as BusinessError).code + " : " + (err as BusinessError).message);
      console.log(TEST_TAG + " moveTo  result: fail.");
    }
  }

  getPositionToWindow() {
    let positionToWindow = this.rootNode?.getPositionToWindow();
    console.log(TEST_TAG + JSON.stringify(positionToWindow));
  }

  getPositionToParent() {
    let positionToParent = this.rootNode?.getPositionToParent();
    console.log(TEST_TAG + JSON.stringify(positionToParent));
  }

  getPositionToScreen() {
    let positionToScreen = this.rootNode?.getPositionToScreen();
    console.log(TEST_TAG + JSON.stringify(positionToScreen));
  }

  getPositionToWindowWithTransform() {
    let positionToWindowWithTransform = this.rootNode?.getPositionToWindowWithTransform();
    console.log(TEST_TAG + JSON.stringify(positionToWindowWithTransform));
  }

  getPositionToParentWithTransform() {
    let positionToParentWithTransform = this.rootNode?.getPositionToParentWithTransform();
    console.log(TEST_TAG + JSON.stringify(positionToParentWithTransform));
  }

  getPositionToScreenWithTransform() {
    let positionToScreenWithTransform = this.rootNode?.getPositionToScreenWithTransform();
    console.log(TEST_TAG + JSON.stringify(positionToScreenWithTransform));
  }

  getMeasuredSize() {
    let measuredSize = this.frameNode?.getMeasuredSize();
    console.log(TEST_TAG + JSON.stringify(measuredSize));
  }

  getLayoutPosition() {
    let layoutPosition = this.frameNode?.getLayoutPosition();
    console.log(TEST_TAG + JSON.stringify(layoutPosition));
  }

  getUserConfigBorderWidth() {
    let userConfigBorderWidth = this.frameNode?.getUserConfigBorderWidth();
    console.log(TEST_TAG + JSON.stringify(userConfigBorderWidth));
  }

  getUserConfigPadding() {
    let userConfigPadding = this.frameNode?.getUserConfigPadding();
    console.log(TEST_TAG + JSON.stringify(userConfigPadding));
  }

  getUserConfigMargin() {
    let userConfigMargin = this.frameNode?.getUserConfigMargin();
    console.log(TEST_TAG + JSON.stringify(userConfigMargin));
  }

  getUserConfigSize() {
    let userConfigSize = this.frameNode?.getUserConfigSize();
    console.log(TEST_TAG + JSON.stringify(userConfigSize));
  }

  getId() {
    let id = this.frameNode?.getId();
    console.log(TEST_TAG + id);
  }

  getUniqueId() {
    let uniqueId = this.frameNode?.getUniqueId();
    console.log(TEST_TAG + uniqueId);
  }

  getNodeType() {
    let nodeType = this.frameNode?.getNodeType();
    console.log(TEST_TAG + nodeType);
  }

  getOpacity() {
    let opacity = this.frameNode?.getOpacity();
    console.log(TEST_TAG + JSON.stringify(opacity));
  }

  isVisible() {
    let visible = this.frameNode?.isVisible();
    console.log(TEST_TAG + JSON.stringify(visible));
  }

  isClipToFrame() {
    let clipToFrame = this.frameNode?.isClipToFrame();
    console.log(TEST_TAG + JSON.stringify(clipToFrame));
  }

  isAttached() {
    let attached = this.frameNode?.isAttached();
    console.log(TEST_TAG + JSON.stringify(attached));
  }

  getInspectorInfo() {
    let inspectorInfo = this.frameNode?.getInspectorInfo();
    console.log(TEST_TAG + JSON.stringify(inspectorInfo));
  }

  setCrossLanguageOptions() {
    console.log(TEST_TAG + " getCrossLanguageOptions " + JSON.stringify(this.frameNode?.getCrossLanguageOptions()));
    try {
      this.frameNode?.setCrossLanguageOptions({
        attributeSetting: true
      });
      console.log(TEST_TAG + " setCrossLanguageOptions success.");
    } catch (err) {
      console.log(TEST_TAG + " " + (err as BusinessError).code + " : " + (err as BusinessError).message);
      console.log(TEST_TAG + " setCrossLanguageOptions fail.");
    }
    console.log(TEST_TAG + " getCrossLanguageOptions " + JSON.stringify(this.frameNode?.getCrossLanguageOptions()));
  }

  throwError() {
    try {
      this.rootNode!.getParent()!.clearChildren();
    } catch (err) {
      console.log(TEST_TAG + " " + (err as BusinessError).code + " : " + (err as BusinessError).message);
    }
    try {
      this.rootNode!.getParent()!.appendChild(new FrameNode(this.uiContext));
    } catch (err) {
      console.log(TEST_TAG + " " + (err as BusinessError).code + " : " + (err as BusinessError).message);
    }
    try {
      this.rootNode!.getParent()!.removeChild(this.rootNode!.getParent()!.getChild(0));
    } catch (err) {
      console.log(TEST_TAG + " " + (err as BusinessError).code + " : " + (err as BusinessError).message);
    }
  }
}

@Entry
@Component
struct Index {
  private myNodeController: MyNodeController = new MyNodeController();
  private scroller: Scroller = new Scroller();
  @State index: number = 0;

  build() {
    Scroll(this.scroller) {
      Column({ space: 8 }) {
        Column() {
          Row() {
            Button("ADD")
              .onClick(() => {
                this.index++;
              })
            Button("DEC")
              .onClick(() => {
                this.index--;
              })
          }

          Text("Current index is " + this.index)
            .textAlign(TextAlign.Center)
            .borderRadius(10)
            .backgroundColor(0xFFFFFF)
            .width('100%')
            .fontSize(16)
        }

        Column() {
          Text("This is a NodeContainer.")
            .textAlign(TextAlign.Center)
            .borderRadius(10)
            .backgroundColor(0xFFFFFF)
            .width('100%')
            .fontSize(16)
          NodeContainer(this.myNodeController)
            .borderWidth(1)
            .width(300)
            .height(100)
        }

        Button("appendChild")
          .width(300)
          .onClick(() => {
            this.myNodeController.appendChild();
          })
        Button("insertChildAfter")
          .width(300)
          .onClick(() => {
            this.myNodeController.insertChildAfter(this.index);
          })
        Button("removeChild")
          .width(300)
          .onClick(() => {
            this.myNodeController.removeChild(this.index);
          })
        Button("clearChildren")
          .width(300)
          .onClick(() => {
            this.myNodeController.clearChildren();
          })
        Button("getChildNumber")
          .width(300)
          .onClick(() => {
            this.myNodeController.getChildNumber();
          })
        Button("searchFrameNode")
          .width(300)
          .onClick(() => {
            this.myNodeController.searchFrameNode();
          })
        Button("moveFrameNode")
          .width(300)
          .onClick(() => {
            this.myNodeController.moveFrameNode();
          })
        Button("getPositionToWindow")
          .width(300)
          .onClick(() => {
            this.myNodeController.getPositionToWindow();
          })
        Button("getPositionToParent")
          .width(300)
          .onClick(() => {
            this.myNodeController.getPositionToParent();
          })
        Button("getPositionToScreen")
          .width(300)
          .onClick(() => {
            this.myNodeController.getPositionToScreen();
          })
        Button("getPositionToParentWithTransform")
          .width(300)
          .onClick(() => {
            this.myNodeController.getPositionToParentWithTransform();
          })
        Button("getPositionToWindowWithTransform")
          .width(300)
          .onClick(() => {
            this.myNodeController.getPositionToWindowWithTransform();
          })
        Button("getPositionToScreenWithTransform")
          .width(300)
          .onClick(() => {
            this.myNodeController.getPositionToScreenWithTransform();
          })
        Button("getMeasuredSize")
          .width(300)
          .onClick(() => {
            this.myNodeController.getMeasuredSize();
          })
        Button("getLayoutPosition")
          .width(300)
          .onClick(() => {
            this.myNodeController.getLayoutPosition();
          })
        Button("getUserConfigBorderWidth")
          .width(300)
          .onClick(() => {
            this.myNodeController.getUserConfigBorderWidth();
          })
        Button("getUserConfigPadding")
          .width(300)
          .onClick(() => {
            this.myNodeController.getUserConfigPadding();
          })
        Button("getUserConfigMargin")
          .width(300)
          .onClick(() => {
            this.myNodeController.getUserConfigMargin();
          })
        Button("getUserConfigSize")
          .width(300)
          .onClick(() => {
            this.myNodeController.getUserConfigSize();
          })
        Button("getId")
          .width(300)
          .onClick(() => {
            this.myNodeController.getId();
          })
        Button("getUniqueId")
          .width(300)
          .onClick(() => {
            this.myNodeController.getUniqueId();
          })
        Button("getNodeType")
          .width(300)
          .onClick(() => {
            this.myNodeController.getNodeType();
          })
        Button("getOpacity")
          .width(300)
          .onClick(() => {
            this.myNodeController.getOpacity();
          })
        Button("isVisible")
          .width(300)
          .onClick(() => {
            this.myNodeController.isVisible();
          })
        Button("isClipToFrame")
          .width(300)
          .onClick(() => {
            this.myNodeController.isClipToFrame();
          })
        Button("isAttached")
          .width(300)
          .onClick(() => {
            this.myNodeController.isAttached();
          })
        Button("getInspectorInfo")
          .width(300)
          .onClick(() => {
            this.myNodeController.getInspectorInfo();
          })
        Button("getCustomProperty")
          .width(300)
          .onClick(() => {
            const uiContext: UIContext = this.getUIContext();
            if (uiContext) {
              const node: FrameNode | null = uiContext.getFrameNodeById("Test_Button") || null;
              if (node) {
                for (let i = 1; i < 4; i++) {
                  const key = 'customProperty' + i;
                  const property = node.getCustomProperty(key);
                  console.log(TEST_TAG + key, JSON.stringify(property));
                }
              }
            }
          })
          .id('Test_Button')
          .customProperty('customProperty1', {
            'number': 10,
            'string': 'this is a string',
            'bool': true,
            'object': {
              'name': 'name',
              'value': 100
            }
          })
          .customProperty('customProperty2', {})
          .customProperty('customProperty2', undefined)
        Button("setCrossLanguageOptions")
          .width(300)
          .onClick(() => {
            this.myNodeController.setCrossLanguageOptions();
          })
        Button("throwError")
          .width(300)
          .onClick(() => {
            this.myNodeController.throwError();
          })
      }
      .width("100%")
    }
    .scrollable(ScrollDirection.Vertical) // 滚动方向纵向
  }
}

LazyForEach场景节点操作示例

import { NodeController, FrameNode, UIContext, BuilderNode, ExpandMode, LengthUnit } from '@kit.ArkUI';

const TEST_TAG: string = "FrameNode "

// BasicDataSource实现了IDataSource接口,用于管理listener监听,以及通知LazyForEach数据更新
class BasicDataSource implements IDataSource {
  private listeners: DataChangeListener[] = [];
  private originDataArray: string[] = [];

  public totalCount(): number {
    return 0;
  }

  public getData(index: number): string {
    return this.originDataArray[index];
  }

  // 该方法为框架侧调用,为LazyForEach组件向其数据源处添加listener监听
  registerDataChangeListener(listener: DataChangeListener): void {
    if (this.listeners.indexOf(listener) < 0) {
      console.info('add listener');
      this.listeners.push(listener);
    }
  }

  // 该方法为框架侧调用,为对应的LazyForEach组件在数据源处去除listener监听
  unregisterDataChangeListener(listener: DataChangeListener): void {
    const pos = this.listeners.indexOf(listener);
    if (pos >= 0) {
      console.info('remove listener');
      this.listeners.splice(pos, 1);
    }
  }

  // 通知LazyForEach组件需要重载所有子组件
  notifyDataReload(): void {
    this.listeners.forEach(listener => {
      listener.onDataReloaded();
    })
  }

  // 通知LazyForEach组件需要在index对应索引处添加子组件
  notifyDataAdd(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataAdd(index);
      // 写法2:listener.onDatasetChange([{type: DataOperationType.ADD, index: index}]);
    })
  }

  // 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件
  notifyDataChange(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataChange(index);
      // 写法2:listener.onDatasetChange([{type: DataOperationType.CHANGE, index: index}]);
    })
  }

  // 通知LazyForEach组件需要在index对应索引处删除该子组件
  notifyDataDelete(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataDelete(index);
      // 写法2:listener.onDatasetChange([{type: DataOperationType.DELETE, index: index}]);
    })
  }

  // 通知LazyForEach组件将from索引和to索引处的子组件进行交换
  notifyDataMove(from: number, to: number): void {
    this.listeners.forEach(listener => {
      listener.onDataMove(from, to);
      // 写法2:listener.onDatasetChange(
      //         [{type: DataOperationType.EXCHANGE, index: {start: from, end: to}}]);
    })
  }

  notifyDatasetChange(operations: DataOperation[]): void {
    this.listeners.forEach(listener => {
      listener.onDatasetChange(operations);
    })
  }
}

class MyDataSource extends BasicDataSource {
  private dataArray: string[] = []

  public totalCount(): number {
    return this.dataArray.length;
  }

  public getData(index: number): string {
    return this.dataArray[index];
  }

  public addData(index: number, data: string): void {
    this.dataArray.splice(index, 0, data);
    this.notifyDataAdd(index);
  }

  public pushData(data: string): void {
    this.dataArray.push(data);
    this.notifyDataAdd(this.dataArray.length - 1);
  }
}

class Params {
  data: MyDataSource | null = null;
  scroller: Scroller | null = null;
  constructor(data: MyDataSource, scroller: Scroller) {
    this.data = data;
    this.scroller = scroller;
  }
}

@Builder
function buildData(params: Params) {
  List({ scroller: params.scroller }) {
    LazyForEach(params.data, (item: string) => {
      ListItem() {
        Column() {
          Text(item)
            .fontSize(20)
            .onAppear(() => {
              console.log(TEST_TAG + " node appear: " + item)
            })
            .backgroundColor(Color.Pink)
            .margin({
              top: 30,
              bottom: 30,
              left: 10,
              right: 10
            })
        }
      }
      .id(item)
    }, (item: string) => item)
  }
  .cachedCount(5)
  .listDirection(Axis.Horizontal)
}

class MyNodeController extends NodeController {
  private rootNode: FrameNode | null = null;
  private uiContext: UIContext | null = null;
  private data: MyDataSource = new MyDataSource();
  private scroller: Scroller = new Scroller();

  makeNode(uiContext: UIContext): FrameNode | null {
    this.uiContext = uiContext;
    for (let i = 0; i <= 20; i++) {
      this.data.pushData(`N${i}`);
    }
    const params: Params = new Params(this.data, this.scroller);
    const dataNode: BuilderNode<[Params]> = new BuilderNode(uiContext);
    dataNode.build(wrapBuilder<[Params]>(buildData), params);
    this.rootNode = dataNode.getFrameNode();
    const scrollToIndexOptions: ScrollToIndexOptions = {
      extraOffset: {
        value: 20, unit: LengthUnit.VP
      }
    };
    this.scroller.scrollToIndex(6, true, ScrollAlign.START, scrollToIndexOptions);
    return this.rootNode;
  }

  getFirstChildIndexWithoutExpand() {
    console.log(`${TEST_TAG} getFirstChildIndexWithoutExpand: ${this.rootNode!.getFirstChildIndexWithoutExpand()}`);
  }

  getLastChildIndexWithoutExpand() {
    console.log(`${TEST_TAG} getLastChildIndexWithoutExpand: ${this.rootNode!.getLastChildIndexWithoutExpand()}`);
  }

  getChildWithNotExpand() {
    const childNode = this.rootNode!.getChild(3, ExpandMode.NOT_EXPAND);
    console.log(TEST_TAG + " getChild(3, ExpandMode.NOT_EXPAND): " + childNode!.getId());
    if (childNode!.getId() === "N9") {
      console.log(TEST_TAG + " getChild(3, ExpandMode.NOT_EXPAND)  result: success.");
    } else {
      console.log(TEST_TAG + " getChild(3, ExpandMode.NOT_EXPAND)  result: fail.");
    }
  }

  getChildWithExpand() {
    const childNode = this.rootNode!.getChild(3, ExpandMode.EXPAND);
    console.log(TEST_TAG + " getChild(3, ExpandMode.EXPAND): " + childNode!.getId());
    if (childNode!.getId() === "N3") {
      console.log(TEST_TAG + " getChild(3, ExpandMode.EXPAND)  result: success.");
    } else {
      console.log(TEST_TAG + " getChild(3, ExpandMode.EXPAND)  result: fail.");
    }
  }
  
  getChildWithLazyExpand() {
    const childNode = this.rootNode!.getChild(3, ExpandMode.LAZY_EXPAND);
    console.log(TEST_TAG + " getChild(3, ExpandMode.LAZY_EXPAND): " + childNode!.getId());
    if (childNode!.getId() === "N3") {
      console.log(TEST_TAG + " getChild(3, ExpandMode.LAZY_EXPAND)  result: success.");
    } else {
      console.log(TEST_TAG + " getChild(3, ExpandMode.LAZY_EXPAND)  result: fail.");
    }
  }
}

@Entry
@Component
struct Index {
  private myNodeController: MyNodeController = new MyNodeController();
  private scroller: Scroller = new Scroller();

  build() {
    Scroll(this.scroller) {
      Column({ space: 8 }) {
        Column() {
          Text("This is a NodeContainer.")
            .textAlign(TextAlign.Center)
            .borderRadius(10)
            .backgroundColor(0xFFFFFF)
            .width('100%')
            .fontSize(16)
          NodeContainer(this.myNodeController)
            .borderWidth(1)
            .width(300)
            .height(100)
        }

        Button("getFirstChildIndexWithoutExpand")
          .width(300)
          .onClick(() => {
            this.myNodeController.getFirstChildIndexWithoutExpand();
          })
        Button("getLastChildIndexWithoutExpand")
          .width(300)
          .onClick(() => {
            this.myNodeController.getLastChildIndexWithoutExpand();
          })
        Button("getChildWithNotExpand")
          .width(300)
          .onClick(() => {
            this.myNodeController.getChildWithNotExpand();
          })
        Button("getChildWithExpand")
          .width(300)
          .onClick(() => {
            this.myNodeController.getChildWithExpand();
          })
        Button("getChildWithLazyExpand")
          .width(300)
          .onClick(() => {
            this.myNodeController.getChildWithLazyExpand();
          })
      }
      .width("100%")
    }
    .scrollable(ScrollDirection.Vertical) // 滚动方向纵向
  }
}

基础事件示例

import { NodeController, FrameNode } from '@kit.ArkUI';

class MyNodeController extends NodeController {
  public rootNode: FrameNode | null = null;

  makeNode(uiContext: UIContext): FrameNode | null {
    this.rootNode = new FrameNode(uiContext);
    this.rootNode.commonAttribute.width(100)
      .height(100)
      .backgroundColor(Color.Pink);
    this.addCommonEvent(this.rootNode);
    return this.rootNode;
  }

  addCommonEvent(frameNode: FrameNode) {
    frameNode.commonEvent.setOnHover(((isHover: boolean, event: HoverEvent): void => {
      console.log(`isHover FrameNode: ${isHover}`);
      console.log(`isHover FrameNode: ${JSON.stringify(event)}`);
      event.stopPropagation();
    }))
    frameNode.commonEvent.setOnClick((event: ClickEvent) => {
      console.log(`Click FrameNode: ${JSON.stringify(event)}`)
    })
    frameNode.commonEvent.setOnTouch((event: TouchEvent) => {
      console.log(`touch FrameNode: ${JSON.stringify(event)}`)
    })
    frameNode.commonEvent.setOnAppear(() => {
      console.log(`on Appear FrameNode`)
    })
    frameNode.commonEvent.setOnDisappear(() => {
      console.log(`onDisAppear FrameNode`)
    })
    frameNode.commonEvent.setOnFocus(() => {
      console.log(`onFocus FrameNode`)
    })
    frameNode.commonEvent.setOnBlur(() => {
      console.log(`onBlur FrameNode`)
    })
    frameNode.commonEvent.setOnKeyEvent((event: KeyEvent) => {
      console.log(`Key FrameNode: ${JSON.stringify(event)}`)
    })
    frameNode.commonEvent.setOnMouse((event: MouseEvent) => {
      console.log(`Mouse FrameNode: ${JSON.stringify(event)}`)
    })
    frameNode.commonEvent.setOnSizeChange((oldValue: SizeOptions, newValue: SizeOptions) => {
      console.info(`onSizeChange FrameNode: oldValue is ${JSON.stringify(oldValue)} value is ${JSON.stringify(newValue)}`)
    })
  }
}

@Entry
@Component
struct Index {
  @State index: number = 0;
  private myNodeController: MyNodeController = new MyNodeController();

  build() {
    Column() {
      Button("add CommonEvent to Text")
        .onClick(() => {
          this.myNodeController!.addCommonEvent(this.myNodeController!.rootNode!.getParent()!.getPreviousSibling() !)
        })
      Text("this is a Text")
        .fontSize(16)
        .borderWidth(1)
        .onHover(((isHover: boolean, event: HoverEvent): void => {
          console.log(`isHover Text: ${isHover}`);
          console.log(`isHover Text: ${JSON.stringify(event)}`);
          event.stopPropagation();
        }))
        .onClick((event: ClickEvent) => {
          console.log(`Click Text    : ${JSON.stringify(event)}`)
        })
        .onTouch((event: TouchEvent) => {
          console.log(`touch Text    : ${JSON.stringify(event)}`)
        })
        .onAppear(() => {
          console.log(`on Appear Text`)
        })
        .onDisAppear(() => {
          console.log(`onDisAppear Text`)
        })
        .onFocus(() => {
          console.log(`onFocus Text`)
        })
        .onBlur(() => {
          console.log(`onBlur Text`)
        })
        .onKeyEvent((event: KeyEvent) => {
          console.log(`Key Text    : ${JSON.stringify(event)}`)
        })
        .onMouse((event: MouseEvent) => {
          console.log(`Mouse Text : ${JSON.stringify(event)}`)
        })
        .onSizeChange((oldValue: SizeOptions, newValue: SizeOptions) => {
          console.info(`onSizeChange Text: oldValue is ${JSON.stringify(oldValue)} value is ${JSON.stringify(newValue)}`)
        })
      NodeContainer(this.myNodeController)
        .borderWidth(1)
        .width(300)
        .height(100)
    }.width("100%")
  }
}

LazyForEach场景基础事件使用示例

// index.ets
import {Track, TrackManager, TrackNode} from "./track"

@Builder
function page1() {
  Column() {
    Text("Page1")
    PageList().height("90%")
    Button("DumpMessage")
      .onClick(() => {
        TrackManager.get().dump()
      })

  }.width("100%").height("100%")
}

class BasicDataSource implements IDataSource {
  private listeners: DataChangeListener[] = [];
  private originDataArray: string[] = [];

  public totalCount(): number {
    return 0;
  }

  public getData(index: number): string {
    return this.originDataArray[index];
  }

  // 该方法为框架侧调用,为LazyForEach组件向其数据源处添加listener监听
  registerDataChangeListener(listener: DataChangeListener): void {
    if (this.listeners.indexOf(listener) < 0) {
      console.info('add listener');
      this.listeners.push(listener);
    }
  }

  // 该方法为框架侧调用,为对应的LazyForEach组件在数据源处去除listener监听
  unregisterDataChangeListener(listener: DataChangeListener): void {
    const pos = this.listeners.indexOf(listener);
    if (pos >= 0) {
      console.info('remove listener');
      this.listeners.splice(pos, 1);
    }
  }

  // 通知LazyForEach组件需要重载所有子组件
  notifyDataReload(): void {
    this.listeners.forEach(listener => {
      listener.onDataReloaded();
    })
  }

  // 通知LazyForEach组件需要在index对应索引处添加子组件
  notifyDataAdd(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataAdd(index);
    })
  }

  // 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件
  notifyDataChange(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataChange(index);
    })
  }

  // 通知LazyForEach组件需要在index对应索引处删除该子组件
  notifyDataDelete(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataDelete(index);
    })
  }

  // 通知LazyForEach组件将from索引和to索引处的子组件进行交换
  notifyDataMove(from: number, to: number): void {
    this.listeners.forEach(listener => {
      listener.onDataMove(from, to);
    })
  }
}

class MyDataSource extends BasicDataSource {
  private dataArray: string[] = [];

  public totalCount(): number {
    return this.dataArray.length;
  }

  public getData(index: number): string {
    return this.dataArray[index];
  }

  public addData(index: number, data: string): void {
    this.dataArray.splice(index, 0, data);
    this.notifyDataAdd(index);
  }

  public pushData(data: string): void {
    this.dataArray.push(data);
    this.notifyDataAdd(this.dataArray.length - 1);
  }
}

@Component
struct PageList {
  private data: MyDataSource = new MyDataSource();

  aboutToAppear() {
    for (let i = 0; i <= 100; i++) {
      this.data.pushData(`Hello ${i}`)
    }
  }

  build() {
    List({ space: 3 }) {
      LazyForEach(this.data, (item: string, index: number) => {
        ListItem() {
          // 通过TrackNode对组件进行封装埋点
          TrackNode({track: new Track().tag("xxx"+ item).id(index + 30000)}) {
            Row() {
              Text(item).fontSize(30)
                .onClick(() => {
                })
            }.margin({ left: 10, right: 10 })
          }
        }
      }, (item: string) => item)
    }.cachedCount(5)
  }
}


@Entry
@Component
struct TrackTest {
  pageInfos: NavPathStack = new NavPathStack()
  build() {
    Row() {
      TrackNode({ track: new Track().tag("root").id(10000)}) {
        page1()
      }
    }
  }

  aboutToAppear(): void {
    TrackManager.get().startListenClick(this.getUIContext())
  }
}
// ./track.ets
import { FrameNode, Rect } from '@kit.ArkUI';

@Component
export struct TrackNode {
  @BuilderParam closer: VoidCallback = this.defaultBuilder
  track: Track | null = null
  trackShadow: TrackShadow = new TrackShadow()

  @Builder defaultBuilder() {
  }

  build() {
    this.closer()
  }

  aboutToAppear(): void {
    // 稍后使用onDidBuild
  }

  aboutToDisappear(): void {
    TrackManager.get().removeTrack(this.trackShadow.id)
    console.log("Track disappear:" + this.trackShadow.id)
  }

  onDidBuild(): void {
    // 构建埋点的虚拟树,获取的node为当前页面的根节点(用例中为Row)。
    let uid = this.getUniqueId()
    let node: FrameNode | null = this.getUIContext().getFrameNodeByUniqueId(uid);
    console.log("Track onDidBuild node:" + node?.getNodeType())
    if (node === null) {
      return
    }
    this.trackShadow.node = node
    this.trackShadow.id = node?.getUniqueId()
    this.trackShadow.track = this.track;
    TrackManager.get().addTrack(this.trackShadow.id, this.trackShadow)
    // 通过setOnVisibleAreaApproximateChange监听记录埋点组件的可视区域。
    node?.commonEvent.setOnVisibleAreaApproximateChange(
      { ratios: [0, 0.1, 0.2, 0.5, 0.8, 1], expectedUpdateInterval: 500 },
      (ratioInc: boolean, ratio: number) => {
        console.log(`Node ${node?.getUniqueId()}:${node?.getNodeType()} is visibleRatio is ${ratio}`);
        this.trackShadow.visibleRatio = ratio
      })

    let parent: FrameNode | null = node?.getParent()

    let attachTrackToParent: (parent: FrameNode | null) => boolean =
      (parent: FrameNode | null) => {
        while (parent !== null) {
          let parentTrack = TrackManager.get().getTrackById(parent.getUniqueId())
          if (parentTrack !== undefined) {
            parentTrack.childIds.add(this.trackShadow.id)
            this.trackShadow.parentId = parentTrack.id
            return true;
          }
          parent = parent.getParent()
        }
        return false;
      }
    let attached = attachTrackToParent(parent);

    if (!attached) {
      node?.commonEvent.setOnAppear(() => {
        let attached = attachTrackToParent(parent);
        if (attached) {
          console.log("Track lazy attached:" + this.trackShadow.id)
        }
      })
    }
  }
}

export class Track {
  public areaPercent: number = 0
  private trackTag: string = ""
  private trackId: number = 0

  constructor() {
  }

  tag(newTag: string): Track {
    this.trackTag = newTag;
    return this;
  }

  id(newId: number): Track {
    this.trackId = newId;
    return this;
  }
}

export class TrackShadow {
  public node: FrameNode | null = null
  public id: number = -1
  public track: Track | null = null
  public childIds: Set<number> = new Set()
  public parentId: number = -1
  public visibleRect: Rect = { left: 0, top: 0, right: 0, bottom: 0 }
  public area: number = 0
  public visibleRatio: number = 0

  // 通过全局dump输出埋点树的信息
  dump(depth: number = 0): void {
    console.log("Track Dp:" + depth + " id:" + this.id + " areaPer:" + this.track?.areaPercent + " visibleRatio:" + this.visibleRatio)
    this.childIds.forEach((value: number) => {
      TrackManager.get().getTrackById(value)?.dump(depth + 1)
    })
  }
}

export class TrackManager {
  static instance: TrackManager
  private trackMap: Map<number, TrackShadow> = new Map()
  private rootTrack: TrackShadow | null = null

  static get(): TrackManager {
    if (TrackManager.instance !== undefined) {
      return TrackManager.instance
    }
    TrackManager.instance = new TrackManager()
    return TrackManager.instance
  }

  addTrack(id: number, track: TrackShadow) {
    if (this.trackMap.size == 0) {
      this.rootTrack = track
    }
    console.log("Track add id:" + id)
    this.trackMap.set(id, track)
  }

  removeTrack(id: number) {
    let current = this.getTrackById(id)
    if (current !== undefined) {
      this.trackMap.delete(id)
      let parent = this.getTrackById(current?.parentId)
      parent?.childIds.delete(id)
    }
  }

  getTrackById(id: number): TrackShadow | undefined {
    return this.trackMap.get(id)
  }

  startListenClick(context: UIContext) {
    // 通过无感监听获取FrameNode查找埋点信息。
    context.getUIObserver().on("willClick", (event: ClickEvent, node?: FrameNode) => {
      console.log("Track clicked:" + node)
      if (node == undefined) {
        return
      }
      let track = this.getTrackById(node.getUniqueId())
      track?.dump(0);
    })
  }

  updateVisibleInfo(track: TrackShadow): void {
    // 更新埋点信息
  }

  dump(): void {
    this.rootTrack?.dump(0)
  }
}

手势事件示例

import { NodeController, FrameNode } from '@kit.ArkUI';

class MyNodeController extends NodeController {
  public rootNode: FrameNode | null = null;

  makeNode(uiContext: UIContext): FrameNode | null {
    this.rootNode = new FrameNode(uiContext);
    this.rootNode.commonAttribute.width(100)
      .overlay('This is a FrameNode')
      .backgroundColor(Color.Pink)
      .width('100%')
      .height('100%');
    this.addGestureEvent(this.rootNode);
    return this.rootNode;
  }

  addGestureEvent(frameNode: FrameNode) {
    frameNode.gestureEvent.addGesture(new PanGestureHandler()
        .onActionStart((event: GestureEvent) => {
            console.log(`Pan start: ${JSON.stringify(event)}`);
        })
        .onActionUpdate((event: GestureEvent) => {
            console.log(`Pan update: ${JSON.stringify(event)}`);
        })
        .onActionEnd((event: GestureEvent) => {
            console.log(`Pan end: ${JSON.stringify(event)}`);
        })
        .onActionCancel(() => {
            console.log('Pan cancel');
        })
    )
    frameNode.gestureEvent.addGesture(new LongPressGestureHandler()
        .onAction((event: GestureEvent) => {
            console.log(`Long press action: ${JSON.stringify(event)}`);
        })
        .onActionEnd((event: GestureEvent) => {
            console.log(`Long press action end: ${JSON.stringify(event)}`);
        })
        .onActionCancel(() => {
            console.log('Long press cancel');
        })
    )
    frameNode.gestureEvent.addGesture(new TapGestureHandler()
        .onAction((event: GestureEvent) => {
            console.log(`Tap action: ${JSON.stringify(event)}`);
        })
    )
  }
}

@Entry
@Component
struct Index {
  private myNodeController: MyNodeController = new MyNodeController();

  build() {
    Column() {
      NodeContainer(this.myNodeController)
        .borderWidth(1)
        .width(300)
        .height(300)
    }.width("100%")
  }
}

节点自定义示例

import { UIContext, DrawContext, FrameNode, NodeController, LayoutConstraint, Size, Position } from '@kit.ArkUI';
import { drawing } from '@kit.ArkGraphics2D';

function GetChildLayoutConstraint(constraint: LayoutConstraint, child: FrameNode): LayoutConstraint {
  const size = child.getUserConfigSize();
  const width = Math.max(
    Math.min(constraint.maxSize.width, size.width.value), 
    constraint.minSize.width
    );
  const height = Math.max(
    Math.min(constraint.maxSize.height, size.height.value), 
    constraint.minSize.height
    );
  const finalSize: Size = { width, height };
  const res: LayoutConstraint = {
    maxSize: finalSize,
    minSize: finalSize,
    percentReference: finalSize
  };

  return res;
}

class MyFrameNode extends FrameNode {
  public width: number = 10;
  private space: number = 1;

  onMeasure(constraint: LayoutConstraint): void {
    let sizeRes: Size = { width: 100, height: 100 };
    for (let i = 0;i < this.getChildrenCount();i++) {
      let child = this.getChild(i);
      if (child) {
        let childConstraint = GetChildLayoutConstraint(constraint, child);
        child.measure(childConstraint);
        let size = child.getMeasuredSize();
        sizeRes.height += size.height + this.space;
        sizeRes.width = Math.max(sizeRes.width, size.width);
      }
    }
    this.setMeasuredSize(sizeRes);
  }

  onLayout(position: Position): void {
    let y = 0;
    for (let i = 0;i < this.getChildrenCount();i++) {
      let child = this.getChild(i);
      if (child) {
        child.layout({
          x: 20,
          y: y
        });
        y += child.getMeasuredSize().height + this.space;
      }
    }
    this.setLayoutPosition(position);
  }

  onDraw(context: DrawContext) {
    const canvas = context.canvas;
    const pen = new drawing.Pen();
    pen.setStrokeWidth(5);
    pen.setColor({ alpha: 255, red: 255, green: 0, blue: 0 });
    canvas.attachPen(pen);
    canvas.drawRect({ left: 0, right: this.width, top: 0, bottom: this.width });
    canvas.detachPen();
  }

  addWidth() {
    this.width += 10;
  }
}

class MyNodeController extends NodeController {
  public rootNode: MyFrameNode | null = null;

  makeNode(context: UIContext): FrameNode | null {
    this.rootNode = new MyFrameNode(context);
    this.rootNode?.commonAttribute?.size({ width: 100, height: 100 }).backgroundColor(Color.Green);
    return this.rootNode;
  }
}

@Entry
@Component
struct Index {
  private nodeController: MyNodeController = new MyNodeController();

  build() {
    Row() {
      Column() {
        NodeContainer(this.nodeController)
          .width('100%')
          .height(100)
          .backgroundColor('#FFF0F0F0')
        Button('Invalidate')
          .onClick(() => {
            this.nodeController?.rootNode?.addWidth();
            this.nodeController?.rootNode?.invalidate();
          })
        Button('UpdateLayout')
          .onClick(() => {
            this.nodeController?.rootNode?.setNeedsLayout();
          })
      }
      .width('100%')
      .height('100%')
    }
    .height('100%')
  }
}

NodeAdapter使用示例

import { FrameNode, NodeController, NodeAdapter, typeNode } from '@kit.ArkUI';

class MyNodeAdapter extends NodeAdapter {
  uiContext: UIContext
  cachePool: Array<FrameNode> = new Array();
  changed: boolean = false
  reloadTimes: number = 0;
  data: Array<string> = new Array();
  hostNode?: FrameNode

  constructor(uiContext: UIContext, count: number) {
    super();
    this.uiContext = uiContext;
    this.totalNodeCount = count;
    this.loadData();
  }

  reloadData(count: number): void {
    this.reloadTimes++;
    NodeAdapter.attachNodeAdapter(this, this.hostNode);
    this.totalNodeCount = count;
    this.loadData();
    this.reloadAllItems();
  }

  refreshData(): void {
    let items = this.getAllAvailableItems()
    console.log("UINodeAdapter get All items:" + items.length);
    this.reloadAllItems();
  }

  detachData(): void {
    NodeAdapter.detachNodeAdapter(this.hostNode);
    this.reloadTimes = 0;
  }

  loadData(): void {
    for (let i = 0; i < this.totalNodeCount; i++) {
      this.data[i] = "Adapter ListItem " + i + " r:" + this.reloadTimes;
    }
  }

  changeData(from: number, count: number): void {
    this.changed = !this.changed;
    for (let i = 0; i < count; i++) {
      let index = i + from;
      this.data[index] = "Adapter ListItem " + (this.changed ? "changed:" : "") + index + " r:" + this.reloadTimes;
    }
    this.reloadItem(from, count);
  }

  insertData(from: number, count: number): void {
    for (let i = 0; i < count; i++) {
      let index = i + from;
      this.data.splice(index, 0, "Adapter ListItem " + from + "-" + i);
    }
    this.insertItem(from, count);
    this.totalNodeCount += count;
    console.log("UINodeAdapter after insert count:" + this.totalNodeCount);
  }

  removeData(from: number, count: number): void {
    let arr = this.data.splice(from, count);
    this.removeItem(from, count);
    this.totalNodeCount -= arr.length;
    console.log("UINodeAdapter after remove count:" + this.totalNodeCount);
  }

  moveData(from: number, to: number): void {
    let tmp = this.data.splice(from, 1);
    this.data.splice(to, 0, tmp[0]);
    this.moveItem(from, to);
  }

  onAttachToNode(target: FrameNode): void {
    console.log("UINodeAdapter onAttachToNode id:" + target.getUniqueId());
    this.hostNode = target;
  }

  onDetachFromNode(): void {
    console.log("UINodeAdapter onDetachFromNode");
  }

  onGetChildId(index: number): number {
    console.log("UINodeAdapter onGetChildId:" + index);
    return index;
  }

  onCreateChild(index: number): FrameNode {
    console.log("UINodeAdapter onCreateChild:" + index);
    if (this.cachePool.length > 0) {
      let cacheNode = this.cachePool.pop();
      if (cacheNode !== undefined) {
        console.log("UINodeAdapter onCreateChild reused id:" + cacheNode.getUniqueId());
        let text = cacheNode?.getFirstChild();
        let textNode = text as typeNode.Text;
        textNode?.initialize(this.data[index]).fontSize(20);
        return cacheNode;
      }
    }
    console.log("UINodeAdapter onCreateChild createNew");
    let itemNode = typeNode.createNode(this.uiContext, "ListItem");
    let textNode = typeNode.createNode(this.uiContext, "Text");
    textNode.initialize(this.data[index]).fontSize(20);
    itemNode.appendChild(textNode);
    return itemNode;
  }

  onDisposeChild(id: number, node: FrameNode): void {
    console.log("UINodeAdapter onDisposeChild:" + id);
    if (this.cachePool.length < 10) {
      if (!this.cachePool.includes(node)) {
        console.log("UINodeAdapter caching node id:" + node.getUniqueId());
        this.cachePool.push(node);
      }
    } else {
      node.dispose();
    }
  }

  onUpdateChild(id: number, node: FrameNode): void {
    let index = id;
    let text = node.getFirstChild();
    let textNode = text as typeNode.Text;
    textNode?.initialize(this.data[index]).fontSize(20);
  }
}

class MyNodeAdapterController extends NodeController {
  rootNode: FrameNode | null = null;
  nodeAdapter: MyNodeAdapter | null = null;

  makeNode(uiContext: UIContext): FrameNode | null {
    this.rootNode = new FrameNode(uiContext);
    let listNode = typeNode.createNode(uiContext, "List");
    listNode.initialize({ space: 3 }).borderWidth(2).borderColor(Color.Black);
    this.rootNode.appendChild(listNode);
    this.nodeAdapter = new MyNodeAdapter(uiContext, 100);
    NodeAdapter.attachNodeAdapter(this.nodeAdapter, listNode);
    return this.rootNode;
  }
}

@Entry
@Component
struct ListNodeTest {
  adapterController: MyNodeAdapterController = new MyNodeAdapterController();

  build() {
    Column() {
      Text("ListNode Adapter");
      NodeContainer(this.adapterController)
        .width(300).height(300)
        .borderWidth(1).borderColor(Color.Black);
      Row() {
        Button("Reload")
          .onClick(() => {
            this.adapterController.nodeAdapter?.reloadData(50);
          })
        Button("Change")
          .onClick(() => {
            this.adapterController.nodeAdapter?.changeData(5, 10)
          })
        Button("Insert")
          .onClick(() => {
            this.adapterController.nodeAdapter?.insertData(10, 10);
          })
      }

      Row() {
        Button("Remove")
          .onClick(() => {
            this.adapterController.nodeAdapter?.removeData(10, 10);
          })
        Button("Move")
          .onClick(() => {
            this.adapterController.nodeAdapter?.moveData(2, 5);
          })
        Button("Refresh")
          .onClick(() => {
            this.adapterController.nodeAdapter?.refreshData();
          })
        Button("Detach")
          .onClick(() => {
            this.adapterController.nodeAdapter?.detachData();
          })
      }
    }.borderWidth(1)
    .width("100%")
  }
}

节点复用回收使用示例

import { NodeController, BuilderNode, FrameNode, UIContext } from '@kit.ArkUI';

class Params {
  text: string = "this is a text"
}

@Builder
function buttonBuilder(params: Params) {
  Column() {
    Button(params.text)
      .fontSize(20)
      .borderRadius(8)
      .borderWidth(2)
      .backgroundColor(Color.Grey)
  }
}

class MyNodeController extends NodeController {
  private buttonNode: BuilderNode<[Params]> | null = null;
  private rootNode: FrameNode | null = null;
  private wrapBuilder: WrappedBuilder<[Params]> = wrapBuilder(buttonBuilder);

  makeNode(uiContext: UIContext): FrameNode {
    if (this.rootNode == null) {
      this.rootNode = new FrameNode(uiContext);
      this.buttonNode = new BuilderNode(uiContext);
      this.buttonNode.build(this.wrapBuilder, { text: "This is a Button" });
      this.rootNode.appendChild(this.buttonNode.getFrameNode());
    }
    return this.rootNode;
  }

  onAttach(): void {
    console.log("myButton on attach");
  }

  onDetach(): void {
    console.log("myButton on detach");
  }

  //  onBind时,子节点已经重新上树,此时调用reuse,保证子组件的能重新被复用。
  onBind(containerId: number): void {
    // 该方法触发子组件复用,全局复用场景下,复用FrameNode后端资源。
    this.rootNode?.reuse();
    console.log("myButton reuse");
  }

  //  onUnbind时,子节点已经完全下树,此时调用recycle,保证子组件的能完全被回收。
  onUnbind(containerId: number): void {
    // 该方法触发子组件的回收,全局复用场景下,回收FrameNode后端资源用于重新利用。
    this.rootNode?.recycle();
    console.log("myButton recycle");
  }

  getButtonNode(): BuilderNode<[Params]> | null {
    return this.buttonNode;
  }

  getFrameNode(): FrameNode | null {
    return this.rootNode;
  }
}

@Entry
@Component
struct Index {
  @State buttonShow: boolean = true
  @State buttonIndex: number = 0
  public buttonController: MyNodeController = new MyNodeController();
  private buttonNull: null = null;
  private buttonControllerArray: Array<MyNodeController | null> = [this.buttonController, this.buttonNull]

  build() {
    Column() {
      Row() {
        Button("Bind/Unbind")
          .onClick(() => {
            this.buttonIndex++;
          }).margin(5)
        Button("onAttach/onDetach")
          .onClick(() => {
            this.buttonShow = !this.buttonShow
          }).margin(5)
      }
      if (this.buttonShow) {
        NodeContainer(this.buttonControllerArray[this.buttonIndex % this.buttonControllerArray.length])
      }
    }
    .padding({ left: 35, right: 35 })
    .width("100%")
    .height("100%")
  }
}

获取根节点示例

该示例演示了如何通过FrameNode的getParent接口获取当前页面根节点。

@Component
struct ChildView {
  @State message: string = 'Hello World';

  build() {
    RelativeContainer() {
      Text(this.message)
        .id('HelloWorld')
        .fontSize($r('app.float.page_text_font_size'))
        .fontWeight(FontWeight.Bold)
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
        .onClick(() => {
          // 通过id查询获得Text节点的FrameNode对象。不建议设置多个相同的id的节点。
          let node = this.getUIContext().getFrameNodeById("HelloWorld");
          console.log(`Find HelloWorld Tag:${node!.getNodeType()} id:${node!.getUniqueId()}`);
          // 通过while循环遍历查询页面的根节点。如果当前节点为自定义组件,则会继续遍历其父节点。
          while (node && node.getParent() && node.getParent()!.getUniqueId() > 0) {
            node = node.getParent();
            console.log(`Find FrameNode Tag:${node!.getNodeType()} id:${node!.getUniqueId()}`);
          }
        })
    }
    .height('100%')
    .width('100%')
  }
}

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';

  build() {
    RelativeContainer() {
      ChildView({ message: this.message })
        .height('100%')
        .width('100%')
    }
    .height('100%')
    .width('100%')
  }
}