当前位置: 首页 > news >正文

鸿蒙HarmonyOS界面开发-组件动态创建(一)

组件动态创建

组件预创建可以满足开发者在非build生命周期中进行组件创建,创建后的组件可以进行属性设置、布局计算等操作。之后在页面加载时进行使用,可以极大提升页面响应速度。

利用组件预创建机制,可以利用动画执行过程空闲时间进行组件预创建和属性设置。在动画结束后,再进行属性和布局的更新,节省了组件创建的时间,从而加快了页面渲染。

组件动态添加、更新和删除:

动态添加组件

动态添加组件包括以下步骤:

  1. 创建自定义节点。
  2. 实现NodeController,用于自定义节点的创建、显示、更新等操作的管理,并负责将自定义节点挂载到NodeContainer上。
  3. 实现NodeController的makeNode()方法,makeNode()会在NodeController实例绑定NodeContainer的时候进行回调,并将返回的节点挂载至NodeContainer。
  4. 使用NodeContainer显示自定义节点。

创建自定义节点

首先,准备好需要挂载的节点

import { BuilderNode, FrameNode, NodeController } from '@kit.ArkUI';class Params {text: string = 'Hello World';constructor(text: string) {this.text = text;}
}@Builder
function testBuilder(params: Params) {Column() {Text(params.text).fontSize(50).fontWeight(FontWeight.Bold).margin({bottom: 36})}
} 

实现NodeController

NodeController为抽象类,需要继承并实现NodeController

实现NodeController的makeNode()方法

首先,使用构造函数创建BuilderNode实例。创建BuilderNode对象的时候必须要传入对应的UIContext对象。若BuilderNode作为RenderNode的子节点存在,要求设置RenderOptions的selfIdealSize属性。

然后,使用BuilderNode的build()方法,构建组件树。方法build()需要传入两个参数,第一个参数为通过wrapBuilder()封装的全局@Builder方法。第二个参数为对应的@Builder方法所需的参数对象。若@Builder方法不带参数或者存在默认参数,则build()的第二个参数可以不设置。

class TextNodeController extends NodeController {private textNode: BuilderNode<[Params]> | null = null;private message: string = '';constructor(message: string) {super();this.message = message;}makeNode(context: UIContext): FrameNode | null {// Creating a BuilderNode instancethis.textNode = new BuilderNode(context);// Set the selfIdealSize property// this.textNode = new BuilderNode(context, {selfIdealSize: {width: 100, height :100}});// Build the component tree using the build methodthis.textNode.build(wrapBuilder<[Params]>(testBuilder), new Params(this.message));// Returns the node to be displayedreturn this.textNode.getFrameNode();}
}

显示自定义节点

显示自定义节点依赖声明式渲染容器NodeContainer以及对应的控制类NodeController。

NodeController的makeNode()方法返回的节点会显示在对应的NodeContainer中。由于makeNode()需要返回的为一个FrameNode,因此如果预期显示BuilderNode的时候需要调用对应的BuilderNode的getFrameNode()方法,获取其根节点,详细代码如上TextNodeController中所示。

然后,在页面内新增声明式渲染容器NodeContainer,创建工具类NodeController。通过NodeController将MakeNode中返回的节点在声明式渲染容器中进行显示。

@Entry
@Component
struct Index {@State message: string = "hello";private textNodeController: TextNodeController = new TextNodeController(this.message);build() {Row() {Column() {NodeContainer(this.textNodeController).width('100%').height(100).backgroundColor('#FFF0F0F0')}.width('100%').height('100%')}.height('100%')}
}

动态删除组件

通过条件控制语句可以将NodeContainer节点进行移除或者显示。如示例代码,将this.isShow更改为false则将节点从界面上移除。

@Entry
@Component
struct Index {@State message: string = "hello";@State isShow: boolean = true;private textNodeController: TextNodeController = new TextNodeController(this.message);build() {Row() {Column() {if (this.isShow) {NodeContainer(this.textNodeController).width('100%').height(100).backgroundColor('#FFF0F0F0')}Button('isShow').onClick(() => {this.isShow = false;})}.width('100%').height('100%')}.height('100%')}
}

动态更新组件

动态将NodeContainer上的节点替换,依赖于NodeController的makeNode()和rebuild()方法。rebuild方法会触发makeNode的回调,刷新NodeContainer上显示的节点;makeNode()方法返回的为null,则移除NodeContainer下挂载的节点。

class TextNodeController extends NodeController {private textNode: BuilderNode<[Params]> | null = null;private message: string = '';constructor(message: string) {super();this.message = message;}makeNode(context: UIContext): FrameNode | null {// With the addition of null handling, the following code is executed only when the BuilderNode is created for the first time; when replacing a node, textNode is not nullif (this.textNode == null) {this.textNode = new BuilderNode(context);this.textNode.build(wrapBuilder<[Params]>(testBuilder), new Params(this.message));}return this.textNode.getFrameNode();}replaceBuilderNode(newNode: BuilderNode<Object[]>) {this.textNode = newNode;// The rebuild method re-calls the makeNode method.this.rebuild();}
}

开发者可以根据实际情况创建新的节点,参考示例代码如下所示:

// ...
@Entry
@Component
struct Index {@State message: string = "hello";@State isShow: boolean = true;private textNodeController: TextNodeController = new TextNodeController(this.message);// private count = 0;build() {Row() {Column() {if (this.isShow) {NodeContainer(this.textNodeController).width('100%').height(100).backgroundColor('#FFF0F0F0')}Button('replaceNode').onClick(() => {this.textNodeController.replaceBuilderNode(this.buildNewNode());})}.width('100%').height('100%')}.height('100%')}buildNewNode(): BuilderNode<[Params]> {let uiContext: UIContext = this.getUIContext();let message = 'newNode';let textNode = new BuilderNode<[Params]>(uiContext);textNode.build(wrapBuilder<[Params]>(testBuilder), new Params(message))return textNode;}
}

NodeController生命周期

NodeController用于控制和反馈对应的NodeContainer上的节点的行为,需要与NodeContainer一起使用。下面,对其常用生命周期函数进行说明。

  • makeNode():必须要重写的方法,用于构建节点树、返回节点挂载在对应NodeContainer中。在对应NodeContainer创建绑定当前NodeController的时候调用、或者通过rebuild()方法调用刷新。
  • aboutToResize():当controller对应的NodeContainer在Measure的时候进行回调,入参为节点的布局大小。
  • aboutToAppear():当controller对应的NodeContainer在onAppear()的时候进行回调。
  • aboutToDisappear():当controller对应的NodeContainer在onDisappear()的时候进行回调。
  • onTouchEvent():当NodeController绑定的NodeContainer收到Touch事件时触发此回调。
export abstract class NodeController {abstract makeNode(uiContext: UIContext): FrameNode | null;aboutToResize?(size: Size): void;aboutToAppear?(): void;aboutToDisappear?(): void;abstract rebuild(): void;onTouchEvent?(event: TouchEvent): void;
}

加入班级,来和我一起学习吧:华为开发者学堂


文章转载自:

http://ZwukLcVM.phjyb.cn
http://QoehSW2d.phjyb.cn
http://HzMNT4d8.phjyb.cn
http://8nbLMliC.phjyb.cn
http://JPJ0ckCW.phjyb.cn
http://fSzONccg.phjyb.cn
http://JGbYKmNY.phjyb.cn
http://cNqLsGdr.phjyb.cn
http://BipczZW3.phjyb.cn
http://ppj5kTfC.phjyb.cn
http://2GpRDByD.phjyb.cn
http://6BnkbQTs.phjyb.cn
http://TDQUGZdo.phjyb.cn
http://fikBRgIl.phjyb.cn
http://778ZF46h.phjyb.cn
http://EijQOy2w.phjyb.cn
http://RCzOPKLk.phjyb.cn
http://aZWnK8wI.phjyb.cn
http://hlnJqRj4.phjyb.cn
http://QRsuqy7S.phjyb.cn
http://q9uMjPjJ.phjyb.cn
http://NxJEElxs.phjyb.cn
http://uyeV1wGA.phjyb.cn
http://4q01mJuF.phjyb.cn
http://NqbgGbma.phjyb.cn
http://XPEapX8k.phjyb.cn
http://fkA2Tahd.phjyb.cn
http://1o1Gfmp0.phjyb.cn
http://dNAGiSk6.phjyb.cn
http://Bh8jBjm3.phjyb.cn
http://www.dtcms.com/a/387335.html

相关文章:

  • 网络安全风险评估中元模型构建与实例应用
  • 鸿蒙5.0应用开发——V2装饰器@ObservedV2和@Trace的使用
  • xkInfoScan 是一款集成化的网络信息收集与安全扫描工具,支持 IP / 域名 / URL /信息追踪多维度目标探测
  • 解决 Windows 系统下 TDengine 数据恢复及迁移问题
  • PocketBase 是一个‌开源的轻量级后端框架‌,基于 Go 语言开发
  • 苹果新手机和旧手机怎么传输数据?新手避坑指南
  • Maven 只打包部分模块,跳过单元测试... 常用打包参数
  • 【maven01】依赖管理的工具
  • BP神经网络多输入多输出回归预测+SHAP可解释分析+新数据预测(MATLAB完整源码)
  • MATLAB 时间序列小波周期分析
  • 计算机视觉进阶教学之DNN模块
  • 大模型无需懂MCP:工具调用范式的架构革命与实践指南
  • 剑指offer题单 9.14
  • IIS 站点 http 请求412问题解决
  • Web前端入门:从零开始做网站(视频教程)
  • 本地--Oracle表被锁了该如何处理
  • Doris与Clickhouse分析
  • ByteDance字节前端一面
  • 卫星通信+AI双核驱动,遨游智能三防手机连得上、会思考
  • 云手机通道具有哪些方面的优势
  • 前端实验(二)初识Vue
  • html.
  • 【人工智能与机器人研究】基于多模态的管道非接触式磁记忆检测方法研究
  • DIY Linux 桌面:让电脑再次快速运行
  • MySQL基础入门:开启数据库之旅
  • C++开发者如何开发自己的第一个mac应用(xcode + XIB + Objective-C C++)
  • LabVIEW风洞测试系统稳定性措施
  • Spring Boot 深入剖析:SpringBoot的启动流程
  • 机器人工具标定-记录一下-待验证(没数据)
  • 1.0 Labview中事件结构在while循环中使用注意事项(超时时间)