README.md
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```