1# 使用ArkUI的FrameNode扩展实现动态布局类框架 2 3### 介绍 4 5本示例是[使用ArkUI的FrameNode扩展实现动态布局类框架](./docs/imperative_dynamic_layouts.md) 6的示例代码,主要讲解如何使用ArkUI的FrameNode扩展实现动态布局类框架。 7 8### 效果图预览 9 10 11 12**使用说明** 13 141. 定义DSL用来描述UI。 152. 定义DSL解析逻辑,使用FrameNode来创建对应组件。 163. 使用NodeContainer组件占位,将创建的组件加载到页面中。 17 18### 实现思路 19 201. 定义DSL,DSL一般会使用JSON、XML等数据交换格式来描述UI,本案例使用JSON,详细代码请参考[foo.json](./casesfeature/imperativedynamiclayouts/src/main/ets/jsonpage/foo.json)。 21 22```json 23{ 24 "type": "Column", 25 "css": { 26 "width": "100%" 27 }, 28 "children": [ 29 { 30 "type": "Row", 31 "css": { 32 "width": "100%", 33 "padding": { 34 "left": 15, 35 "right": 15 36 }, 37 "margin": { 38 "top": 5, 39 "bottom": 5 40 }, 41 ... 42 }, 43 ... 44 }, 45 ... 46 ] 47} 48``` 49 502. 定义相应数据结构用于接收UI描述数据,详细代码参考[ImperativeView.ets](./casesfeature/imperativedynamiclayouts/src/main/ets/view/ImperativeView.ets)。 51 52```typescript 53class VM { 54 type?: string 55 content?: string 56 css?: ESObject 57 children?: VM[] 58 id?: string 59} 60``` 61 623. 自定义DSL解析逻辑,且使用carouselNodes保存轮播图节点,方便后续操作节点更新,详细代码参考[ImperativeView.ets](./casesfeature/imperativedynamiclayouts/src/main/ets/view/ImperativeView.ets)。 63```typescript 64let carouselNodes: typeNode.Image[] = []; 65 66function FrameNodeFactory(vm: VM, context: UIContext): FrameNode | null { 67 ... 68 return null; 69} 70 71function setColumnNodeAttr(node: typeNode.Column, css: ESObject) { 72 ... 73} 74 75function setRowNodeAttr(node: typeNode.Row, css: ESObject) { 76 ... 77} 78``` 79 804. 使用NodeContainer组件占位,将创建的组件加载到页面中,详细代码请参考[ImperativeView.ets](./casesfeature/imperativedynamiclayouts/src/main/ets/view/ImperativeView.ets)。 81```typescript 82class ImperativeController extends NodeController { 83 makeNode(uiContext: UIContext): FrameNode | null { 84 return FrameNodeFactory(data, uiContext); 85 } 86} 87 88@Entry 89@Component 90struct ImperativeView { 91 controller: ImperativeController = new ImperativeController(); 92 build() { 93 Column() { 94 NodeContainer(this.controller) 95 } 96 .height('100%') 97 .width('100%') 98 .backgroundColor(Color.Black) 99 } 100} 101``` 102 103### 高性能知识点 104 105使用ArkUI的FrameNode扩展,可以避免创建自定义组件对象和状态变量对象,也无需进行依赖收集,从而显著提升组件创建的速度,并且能更快的组件更新操作以及对组件树结构的直接控制。 106 107### 工程结构&模块类型 108 109 ``` 110 imperativedynamiclayouts // har类型 111 |---jsonpage // 存放描述UI的数据文件 112 |---|---foo.json // 描述UI的数据 113 |---view // 视图 114 |---|---ImperativeView.ets // 视频首页 115 ``` 116 117### 参考资料 118 119[NodeContainer](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-nodecontainer.md#nodecontainer) 120 121[NodeController](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/js-apis-arkui-nodeController.md) 122 123### 相关权限 124 125不涉及 126 127### 依赖 128 129不涉及 130 131### 约束与限制 132 1331. 本示例仅支持标准系统上运行。 134 1352. 本示例已适配API version 12版本SDK。 136 1373. 本示例需要使用DevEco Studio 5.0.0 Release及以上版本才可编译运行。 138 139### 下载 140 141如需单独下载本工程,执行如下命令: 142```bash 143git init 144git config core.sparsecheckout true 145echo /code/UI/ImperativeDynamicLayouts/ > .git/info/sparse-checkout 146git remote add origin https://gitee.com/openharmony/applications_app_samples.git 147git pull origin master 148```