鸿蒙开发:动态添加节点

关键词:组件,节点,上下树

首先要看官网介绍,然后我们开始尝试动态添加节点

首先,我们先创建一个节点类MyNodeController

kotlin 复制代码
class MyNodeController extends NodeController {
  // 将 meg 设为实例属性
  private meg: string = "传入了具体的数据,使用的时候会自动解析";
  private buttonNode: BuilderNode<[string]> | null = null;
  private wrapBuilder: WrappedBuilder<[string]> = wrapBuilder(textBuilder);

  constructor(uiContext: UIContext, meg?: string) {
    super();
    if (meg) {
      this.meg = meg;
      this.makeNode(uiContext);
    }
  }

  makeNode(uiContext: UIContext): FrameNode | null {
    if (this.buttonNode === null) {
      this.buttonNode = new BuilderNode(uiContext);
      this.buttonNode.build(this.wrapBuilder, this.meg);
    }
    return this.buttonNode.getFrameNode();
  }
}

我们将要塞入的自定义结构就是用WrapBuilder封起来,里面放入自定义的组件

全局Builder函数如下

scss 复制代码
@Builder
function textBuilder(message: string) {
  Text(message)
    .fontSize(20)
    .fontWeight(FontWeight.Bold)
}

现在 我们准备创建一个页面,用于渲染节点,通过 NodeContainer进行渲染

因为我这想要让本地数据覆盖类中的数据,更加自定义一些

所以,页面如下

typescript 复制代码
import { BuilderNode, NodeController, UIContext } from '@kit.ArkUI'

@Entry
@Component
struct NodePage {
  @State msg: string = "本地化的数据传入"
  private myNodeController: MyNodeController = new MyNodeController(this.getUIContext(),this.msg)

  build() {
    Column({ space: 10 }) {
      NodeContainer(this.myNodeController)
    }
    .size({ width: "100%", height: "100%" })
    .backgroundColor(Color.Orange)
    .justifyContent(FlexAlign.Center)
    .opacity(0.5)
  }
}

页面如下

但是目前还不够,我们需要数据上的交互才能算完整了功能

这里,我们的思路就是更新节点的数据

类中先更改,添加方法changgeMsg

kotlin 复制代码
// 提供公共方法修改 meg
changeMsg(msg: string) {
  this.meg = msg;
  // 若 buttonNode 已创建,更新节点内容
  if (this.buttonNode) {
    this.buttonNode.build(this.wrapBuilder, this.meg);
  }
}

所以这里单独说的就是,如果直接更改类中的数据,节点数据是不会刷新的

很好,现在,直接在页面中添加按钮,分别是,增加数据的内容,和直接更改数据内容,更新后的所有代码如下

kotlin 复制代码
import { BuilderNode, NodeController, UIContext } from '@kit.ArkUI'

@Entry
@Component
struct NodePage {
  @State msg: string = "本地化的数据传入"
  private myNodeController: MyNodeController = new MyNodeController(this.getUIContext(),this.msg)

  build() {
    Column({ space: 10 }) {
      NodeContainer(this.myNodeController)

      Button("改变文字 加一个好字").onClick(() => {
        this.msg = this.msg + "好 "
        this.myNodeController.changeMsg(this.msg )
      })

      Button("新按钮").onClick(() => {
        this.msg = "new msg"
        this.myNodeController.changeMsg(this.msg)
      })
    }
    .size({ width: "100%", height: "100%" })
    .backgroundColor(Color.Orange)
    .justifyContent(FlexAlign.Center)
    .opacity(0.5)
  }
}

@Builder
function textBuilder(message: string) {
  Text(message)
    .fontSize(20)
    .fontWeight(FontWeight.Bold)
}


class MyNodeController extends NodeController {
  // 将 meg 设为实例属性
  private meg: string = "传入了具体的数据,使用的时候会自动解析";
  private buttonNode: BuilderNode<[string]> | null = null;
  private wrapBuilder: WrappedBuilder<[string]> = wrapBuilder(textBuilder);

  constructor(uiContext: UIContext, meg?: string) {
    super();
    if (meg) {
      this.meg = meg;
      this.makeNode(uiContext);
    }
  }

  // 提供公共方法修改 meg
  changeMsg(msg: string) {
    this.meg = msg;
    // 若 buttonNode 已创建,更新节点内容
    if (this.buttonNode) {
      this.buttonNode.build(this.wrapBuilder, this.meg);
    }
  }

  makeNode(uiContext: UIContext): FrameNode | null {
    if (this.buttonNode === null) {
      this.buttonNode = new BuilderNode(uiContext);
      this.buttonNode.build(this.wrapBuilder, this.meg);
    }
    return this.buttonNode.getFrameNode();
  }
}

代码效果展示如下

到了这里,我们基本就知道应该如何动态添加节点了,不过,我们的知识面还不完整

这里就要介绍一下FrameNode

通过FrameNode我们可以添加节点、删除和获取子节点

我们通过typeNode初始化各种样式组件 然后 配置给frameNode

实现代码如下

scala 复制代码
import { FrameNode, NodeController, typeNode } from '@kit.ArkUI'

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

  build() {
    Column() {
      NodeContainer(this.myNodeController)
    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.Center)
  }
}


class MyNodeController extends NodeController {
  makeNode(uiContext: UIContext): FrameNode {
    let rootNode = new FrameNode(uiContext)
    //创建一个Column组件
    let column = typeNode.createNode(uiContext, "Column")
    column.initialize()
      .width("100%")
      .height("100%")
      .justifyContent(FlexAlign.Center)
    rootNode.appendChild(column)
    //创建一个Text组件
    let text = typeNode.createNode(uiContext, "Text")
    text.initialize("文本组件")
      .fontColor(Color.Red)
      .fontSize(20)
      .padding(10)
      .border({ width: 1, color: Color.Red })
    column.appendChild(text)
    return rootNode
  }
}

当然,这些都是基本的使用和认识,要想熟悉具体的内容,还是离不开官方文档

鸿蒙官方文档链接 developer.huawei.com/consumer/cn...

相关推荐
ljt27249606615 分钟前
Flutter笔记--envied
前端·笔记·flutter
Flynt26 分钟前
React Router v8 升了之后,我花了两天才把项目跑起来
前端·typescript·preact
泯泷7 小时前
手搓JSVMM第 8 篇:函数调用:参数、返回值与调用帧
前端·javascript·前端框架
Sherotree7 小时前
Google Antigravity——Agent 被提到主界面
前端·ide·后端·edge浏览器
里欧跑得慢8 小时前
Flutter 像素级还原:设计稿到代码的视觉无损转换技巧
前端·css·flutter·web
里欧跑得慢8 小时前
Flutter 三方库 function_tree — 鸿蒙应用开发中的动态数学公式解析与计算神器,实现鸿蒙深度适配下的复杂函数逻辑运行时求值实战(适配鸿蒙 HarmonyOS Next ohos)
android·前端·安全·flutter·华为·harmonyos
苏灿烤鱼9 小时前
没有机密文件,也没有付费数据,在浏览器里造一颗"间谍卫星"
前端·javascript·github
泯泷9 小时前
手搓JSVM第 5 篇:写第一个编译器:从 AST 生成 IR
前端·javascript·算法
泯泷9 小时前
手搓JSVM第 7 篇:控制流:if、while 与 jump
前端·javascript·算法
泯泷9 小时前
手搓JSVM第 6 篇:把 IR 编成字节码:emit 与 label fixup
前端·javascript·算法