HarmonyOS(65) ArkUI FrameNode详解

1、Node简介

HarmonyOS(63) ArkUI 自定义占位组件NodeContainer介绍了自定义节点复用的原理(阅读本本篇博文之前,建议先读读这个),在NodeController里有有个makeNode方法:


class MyNodeController extends NodeController {
   
  private buttonNode: BuilderNode<[Params]> | null = null;
  //绑定buttonBuilder
  private wrapBuilder: WrappedBuilder<[Params]> = wrapBuilder(buttonBuilder);
  //当实例绑定的NodeContainer创建的时候进行回调。回调方法将返回一个节点,将该节点挂载至NodeContainer。
 //或者可以通过NodeController的rebuild()方法进行回调的触发。
  makeNode(uiContext: UIContext): FrameNode {
   
    if (this.buttonNode == null) {
   
      //关于BuilderNode下文有所说明
      this.buttonNode = new BuilderNode(uiContext);
 
      this.buttonNode.build(this.wrapBuilder, {
    text: "This is a Button" })
    }
    //返回FrameNode对象,返回的节点将被挂载至NodeContainer的占位节点上。若返回null对象,将清空对应NodeContainer的子节点。
    return this.buttonNode!.getFrameNode()!;
  }
}

在make方法里有两个核心概念:FrameNodeBuilderNode,今天这篇博文就来学习FrameNode
在这里插入图片描述
自定义节点的挂载和显示需要依赖自定义占位节点。现有的自定义节点包括FrameNodeRenderNodeBuilderNode三类对象。FrameNode表示了单个的自定义组件节点(可以对比Android的View),RenderNode表示更加轻量级的渲染节点,BuilderNode对象提供了能够创建、更新原生组件以及组件树的能力。

2、FrameNode

FrameNode表示组件树的实体节点,配合自定义占位容器组件NodeContainer等,在占位容器内挂载一棵自定义的节点树,并对这个节点树中的节点进行动态的增加、修改、删除等操作。基础的FrameNode可以设置通用属性、设置事件回调,并提供完整的自定义能力,包括自定义测量、布局以及绘,具体可以分为两大类能力:完全自定义节点的能力以及原生组件节点代理的能力,可以类比AndroidView/ViewGroup来理解FrameNode,可以通过FrameNode](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-user-defined-arktsnode-framenode-V5)实现类似Android自定义View的功能,。

  • 完全自定义节点:提供完整的自定义能力,包括自定义测量、布局以及绘制,支持节点的动态增、删,设置通用属性,设置事件回调。适用于不自带渲染引擎,需要依赖系统的布局、事件、动画、渲染等能力的场景。

  • 原生组件代理节点:提供原生组件的代理能力,提供遍历节点树的能力,通过组件树上的FrameNode可以遍历整个组件树,并通过节点访问组件的信息或者注册额外的事件监听回调,代理节点可以用于需要遍历整个UI的树形结构,并支持获取原生组件节点的具体信息或者额外注册组件的事件监听回调。适用于结合无感监听的接口实现打点、广告SDK、中台DFX等业务。

2.1、创建和删除节点

FrameNode提供了节点创建和删除的能力。可以通过FrameNode的构造函数创建自定义FrameNode节点,通过构造函数创建的节点对应一个实体的节点。同时,可以通过FrameNode中的dispose接口来实现与实体节点的绑定关系的解除。
示例片段如下,全部代码传送门,文章后面也会有全部代码:

public buttonNode: BuilderNode<[Params]> | null = null;
 public frameNode: FrameNode | null = null;
 public rootNode: FrameNode | null = null;
makeNode(uiContext: UIContext): FrameNode | null {
   
    this.uiContext = uiContext;
    if (this.rootNode == null) {
   
      this.rootNode = new FrameNode(uiContext);
      this.rootNode.commonAttribute
        .width("50%")//占屏幕宽度的一半
        .height(100)
        .borderWidth(1)
        .backgroundColor(Color.Gray)
    }

    if (this.frameNode == null) {
   
      //粉色矩形
      this.frameNode = new FrameNode(uiContext);
      this.frameNode.commonAttribute
        .width("100%")
        .height(50)//高度是rootNode的一半
        .borderWidth(1)
        .position({
    x: 200, y: 0 })//位置信息
        .backgroundColor(Color.Pink);
      this.rootNode.appendChild(this.frameNode);
    }
    //生成两个button,一个是橘黄色的button,一个是粉色的button
    if (this.buttonNode == null) {
   
      this.buttonNode = new BuilderNode<[Params]>(uiContext);
      this.buttonNode.build(this.wrapBuilder, {
    text: "This is a Button" })
      this.rootNode.appendChild(this.buttonNode.getFrameNode())
    }
    return this.rootNode;
  }

上面代码告诉我们可以通过两种方式获取FrameNode
1、直接new FrameNode创建一个FrameNode
2、通过BuilderNode对象的getFrameNode方法获取FrameNode

上面代码创建了三个FrameNode:rootNode、frameNode、buttonNode最终运行效果如下:
在这里插入图片描述
我们可以通过如下方法对rootNode、frameNode、buttonNode进行正删改查功能

2.2、对FrameNode的增删改

为了测试FrameNode的增删改,定义了如下方法:

//该方法在MyNodeController类中
operationFrameNodeWithFrameNode(frameNode: FrameNode | undefined | null) {
   
    if (frameNode) {
   
      console.log(TEST_TAG + " get ArkTSNode success.")
      //调用isModifiable方法判断是否FrameNode可以修改
      console.log(TEST_TAG + " check rootNode whether is modifiable " + frameNode.isModifiable());
    }
    if (this.uiContext) {
   
      //创建黑色方块的FrameNode
      let frameNode1 = new FrameNode(this.uiContext);
      //创建橘色方块的FrameNode
      let frameNode2 = new FrameNode(this.uiContext);
      //设置位置信息
      frameNode1.commonAttribute.size({
    width: 50, height: 50 })
        .backgroundColor(Color.Black)
        .position({
    x: 50, y: 60 })
      frameNode2.commonAttribute.size({
    width: 50, height: 50 })
        .backgroundColor(Color.Orange)
        .position({
    x: 120, y: 60 })
      try {
   
        //插入节点
        frameNode?.appendChild(frameNode1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郭梧悠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值