Bootstrap

HarmonyOS(63) ArkUI 自定义占位组件NodeContainer

1、前言

HarmonyOS(62) ArkUI @Reusable组件复用原理讲了组件复用的原理和场景,还有一个全局型的组件复用场景没有分析,而该场景与NodeContainer息息相关,所以本文来简单分析下NodeContainer的使用方法,为全局型组件复用打下知识基础。

2、NodeContainer和NodeController

3、示例代码

通过NodeController挂载BuilderNode节点。

3.1、创建@Builder

class Params {
  text: string = "this is a text"
}


function buttonBuilder(params: Params) {
  Column() {
    Button(params.text)
      .fontSize(12)
      .borderRadius(8)
      .borderWidth(2)
      .backgroundColor(Color.Orange)
  }
}

上面代码定义了参数对象Params,和一个@Builder,该buttonBuilder创建的UI效果如下:
在这里插入图片描述
后面我们可以将ParamsbuttonBuilder交给WrappedBuilder

3.2、 创建NodeController


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) {
      this.buttonNode = new BuilderNode(uiContext);
 
      this.buttonNode.build(this.wrapBuilder, { text: "This is a Button" })
    }
    //返回FrameNode对象,返回的节点将被挂载至NodeContainer的占位节点上。若返回null对象,将清空对应NodeContainer的子节点。
    return this.buttonNode!.getFrameNode()!;
  }

  aboutToResize(size: Size) {
    console.log("当NodeController绑定的NodeContainer布局的时候触发此回调")
  }

  aboutToAppear() {
    console.log("当NodeController绑定的NodeContainer挂载显示后触发此回调")
  }

  aboutToDisappear() {
    console.log("当NodeController绑定的NodeContainer卸载消失时触发此回调。");
  }

  onTouchEvent(event:TouchEvent) {
    console.log("当NodeController绑定的NodeContainer收到Touch事件时触发此回调");
  }
}

如上代码所示:

  • 通过WrappedBuilder封装全局的@Builder buttonBuilder,并绑定了参数ParamsWrappedBuilder主要解决多个全局@Builder函数会使代码维护起来非常困难,并且页面不整洁的问题。

  • 当实例绑定的NodeContainer创建的时候会回调makeNode方法。该方法将返回FrameNode对象,该对象将被挂载至NodeContainer的占位节点上。若返回null对象,将清空对应NodeContainer的子节点。或者可以通过NodeController的rebuild()方法进行回调的触发。

  • FrameNode表示组件树的实体节点。NodeController可通过BuilderNode持有的FrameNode将其挂载到NodeContainer上,也可通过FrameNode获取RenderNode,挂载到其他FrameNode上。

3.3、 使用NodeCtroller



struct Index {
  //自定义一个MyNodeController
  private myNodeController: MyNodeController = new MyNodeController();

  build() {
    Column() {
      //NodeContainer绑定NodeController
      NodeContainer(this.myNodeController)
    }
    .padding({ left: 35, right: 35, top: 35 })
    .width("100%")
    .height("100%")
  }
}

4、NodeContainer的作用

NodeContainer在全局组件复用场景起到很重要的作用,因为全局型组件可在不同的父组件中复用,并且不适合使用@Builder,详见全局自定义组件复用实现

5、参考资料

HarmonyOS(62) ArkUI @Reusable组件复用原理
NodeContainer
NodeController
FrameNode
WrappedBuilder
全局自定义组件复用实现

;