鸿蒙原生APP开发之声明式UI中实现组件动态创建


📚往期笔录记录📔:


简介

为了解决页面、组件加载缓慢的问题,ArkUI框架提供了动态操作以实现组件预创建,并允许应用在运行时根据实际需要加载渲染相应的组件。动态操作包含动态创建组件(动态添加组件)、动态卸载组件(动态删除组件)等相关操作。动态创建组件指在非build生命周期中进行组件创建,即在build生命周期前提前创建组件。通过动态创建组件,不但可以节省组件创建的时间,提升用户体验,还可以将独立的逻辑进行封装,有助于应用模块化开发。动态卸载组件是对动态创建的组件进行卸载、删除。

组件预创建原理

在声明式范式中,组件仅在build环节中被创建,开发者无法在其他生命周期阶段进行组件的创建,从而引起页面加载慢等问题。与声明式范式不同,ArkUI框架提供的UI动态操作支持组件的预创建。组件预创建可以满足开发者在非build生命周期中进行组件创建,创建后的组件可以进行属性设置、布局计算等操作。之后在页面加载时进行使用,可以极大提升页面响应速度。

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

图1组件预创建原理图

FrameNode自定义节点在动态布局场景下的优势

减少自定义组件创建开销

在采用声明式开发范式中,若使用ArkUI的自定义组件对节点树中的每个节点进行定义,往往会遇到节点创建效率低下的问题。

这主要是因为每个节点在ArkTS引擎中都需要分配内存空间来存储应用程序的自定义组件和状态变量。在节点创建过程中,还必须执行组件ID、组件闭包以及状态变量之间的依赖关系收集等操作。

相比之下,使用ArkUI的 FrameNode ,可以避免创建自定义组件对象和状态变量对象,无需进行依赖收集,从而显著提升组件创建的速度。

组件更新更快

在动态布局类框架的更新场景中,通常存在一个由树形数据结构ViewModelA创建的UI组件树TreeA。当需要使用新的数据结构ViewModelB来更新TreeA时,尽管声明式开发范式可以实现数据驱动的自动更新,但这一过程中却伴随着大量的diff操作,如下图所示。对于ArkTS引擎而言,在对一个复杂组件树(深度超过30层,包含100至200个组件)执行diff算法时,几乎无法在120Hz的刷新率下保持满帧运行。然而,使用ArkUI的FrameNode扩展,框架能够自主掌控更新流程,实现高效的按需剪枝。特别是针对那些仅服务于少数特定业务的动态布局框架,利用这一扩展,可以实现快速的更新操作。

直接操作组件树

使用声明式开发范式还存在组件树结构更新操作困难的痛点,比如将组件树中的一个子树从当前子节点完整移到另一个子节点,使用声明式开发范式无法直接调整组件实例的结构关系,只能通过重新渲染整棵组件树的方式实现上述操作。而使用ArkUI的FrameNode扩展,则

### 鸿蒙系统中原生应用下载页面的开发逻辑 在鸿蒙系统的原生应用开发中,构建一个功能完善的下载页面需要综合考虑用户体验、交互设计以及技术实现细节。以下是关于如何开发鸿蒙系统中原生应用下载页面的核心逻辑: #### 1. 页面布局与组件选择 下载页面通常由以下几个部分组成:应用图标、名称、描述信息、评分星级、下载按钮以及其他附加选项(如分享或收藏)。这些界面元素可以利用 ArkTS 和 eTS 提供的基础 UI 组件实现[^3]。 ```typescript // 使用ArkUI框架定义基本布局结构 @Entry @Component struct DownloadPage { build() { Column({ space: 10 }) { Image($r('app.media.app_icon')).width(100).height(100) Text('App Name').fontSize(20).fontColor('#000000') Text('Description of the app...').fontSize(14).fontColor('#777777') Row({ space: 5 }) { Button('Download Now') // 主要操作按钮 .onClick(() => startDownload()) Button('Share App') // 辅助操作按钮 .onClick(() => shareApp()) } }.padding(20) } function startDownload(): void {} function shareApp(): void {} } ``` 上述代码展示了如何通过 ArkUI 的 `Column` 和 `Row` 定义页面的主要区域分布,并结合 `Image`, `Text`, 和 `Button` 实现基础的功能模块。 --- #### 2. 数据绑定与动态更新 为了使下载页面能够实时反映数据变化(例如下载进度),需引入双向绑定机制。可以通过声明响应式变量并将其关联到界面上的相关控件完成这一目标[^1]。 ```typescript import { State, $raw } from '@ohos/application' const downloadProgress = State<number>(0) function updateProgress(newVal: number): void { downloadProgress.value = newVal; } build() { ... ProgressBar({ progress: $raw(downloadProgress), trackThickness: 5, color: '#FF9800' }) ... } ``` 在此示例中,`State` 被用来创建可观察的状态对象 `downloadProgress`,并通过 `$raw()` 方法将它传递给 `ProgressBar` 控件以展示当前的下载状态。 --- #### 3. 后端服务集成 对于实际的应用程序而言,仅提供前端界面并不足以满足需求;还需要对接后端服务器获取资源链接、执行文件传输等任务。这部分工作可能涉及 HTTP 请求库或者特定 SDK 功能调用[^4]。 假设我们正在处理的是基于 URI 协议启动外部应用程序的情况,则可以在 JSON 文件里预先设定好技能映射关系以便后续触发对应动作: ```json { "abilities": [ { "skills": [ { "entities": ["entity.system.download"], "actions": ["action.system.start_download"], "uris": [{ "scheme": "http", "host": "*.example.com/download/*" }] } ] } ] } ``` 当用户点击某个按钮时,可通过 API 发送 GET 或 POST 请求至指定 URL 地址从而发起真正的下载流程。 --- #### 4. 处理多平台兼容性问题 如果希望所编写的代码能够在不同操作系统之间无缝切换运行的话,则应该优先选用那些已经被验证过的跨平台解决方案——比如采用混合开发模式下的统一语法标准来进行编码作业[^2]。 尽管如此,在某些特殊情况下仍不可避免地会遇到因底层架构差异而导致的行为偏差现象发生。因此建议针对每种目标环境单独测试一遍整个业务链条上的各个环节是否存在潜在隐患之处。 --- ### 总结 综上所述,鸿蒙系统中原生应用下载页面的开发不仅依赖于良好的视觉呈现效果,更离不开稳健的技术支撑体系作为保障依据。从初步规划阶段直至最终部署上线期间都需要保持高度专注态度对待每一个可能出现的问题节点加以妥善解决办法才行得通顺无阻塞状况下达成预期成果表现形式出来供大家参考学习借鉴之用途而已啦!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值