• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 自定义组件的自定义布局
2
3自定义组件的自定义布局用于通过数据计算的方式布局自定义组件内的子组件。
4
5>**说明:**
6>
7>- 本模块首批接口从API version 9开始支持,后续版本的新增接口,采用上角标单独标记接口的起始版本。
8
9## onPlaceChildren<sup>10+</sup>
10
11onPlaceChildren?(selfLayoutInfo: GeometryInfo, children: Array&lt;Layoutable&gt;, constraint: ConstraintSizeOptions):void
12
13ArkUI框架会在自定义组件布局时,将该自定义组件的子节点自身的尺寸范围通过onPlaceChildren传递给该自定义组件。不允许在onPlaceChildren函数中改变状态变量。
14
15**参数:**
16
17| 参数名            | 类型                                                         | 说明               |
18|----------------|------------------------------------------------------------|------------------|
19| selfLayoutInfo | [GeometryInfo](#geometryinfo10)                            | 父组件布局信息。         |
20| children       | Array&lt;[Layoutable](#layoutable10)&gt;                   | 子组件布局信息。         |
21| constraint     | [ConstraintSizeOptions](ts-types.md#constraintsizeoptions) | 父组件constraint信息。 |
22
23## onMeasureSize<sup>10+</sup>
24
25onMeasureSize?(selfLayoutInfo: GeometryInfo, children: Array&lt;Measurable&gt;, constraint: ConstraintSizeOptions):[SizeResult](#sizeresult10)
26
27ArkUI框架会在自定义组件确定尺寸时,将该自定义组件的节点信息和尺寸范围通过onMeasureSize传递给该开发者。不允许在onMeasureSize函数中改变状态变量。
28
29**参数:**
30
31| 参数名            | 类型                                                         | 说明               |
32|----------------|------------------------------------------------------------|------------------|
33| selfLayoutInfo | [GeometryInfo](#geometryinfo10)                            | 父组件布局信息。         |
34| children       | Array&lt;[Measurable](#measurable10)&gt;                   | 子组件布局信息。         |
35| constraint     | [ConstraintSizeOptions](ts-types.md#constraintsizeoptions) | 父组件constraint信息。 |
36
37## GeometryInfo<sup>10+</sup>
38
39父组件布局信息。
40
41| 属性          | 属性类型      | 描述                  |
42|-------------|-----------|---------------------|
43| borderWidth | [EdgeWidth](ts-types.md#edgewidths9) | 父组件边框宽度。<br>单位:vp            |
44| margin      | [Margin](ts-types.md#margin)       | 父组件margin信息。 <br>单位:vp       |
45| padding     | [Padding](ts-types.md#padding)   | 父组件padding信息。<br>单位:vp |
46| width  | number | 测量后的宽。<br>单位:vp<br> **说明:** <br>若值为空时,则返回组件的百分比宽。 |
47| height | number | 测量后的高。<br>单位:vp<br> **说明:** <br>若值为空时,则返回组件的百分比高。 |
48
49
50## Layoutable<sup>10+</sup>
51
52子组件布局信息。
53
54| 属性         | 属性类型                                                    | 描述                  |
55|------------|---------------------------------------------------------|---------------------|
56| measureResult| [MeasureResult](#measureresult10)      | 子组件测量后的尺寸信息。   <br>单位:vp     |
57| layout     | (position: [Position](ts-types.md#position8))&nbsp;=&gt;&nbsp;void | 调用此方法对子组件的位置信息进行限制。 |
58
59## Measurable<sup>10+</sup>
60
61子组件位置信息。
62
63| 属性         | 属性类型                                                                             | 描述                                    |
64|------------|----------------------------------------------------------------------------------|---------------------------------------|
65| measure    | (childConstraint: [ConstraintSizeOptions](ts-types.md#constraintsizeoptions))&nbsp;=&gt;&nbsp;[MeasureResult](#measureresult10) | 调用此方法对子组件的尺寸范围进行限制。<br/>返回值:子组件测量后的尺寸。 |
66
67## MeasureResult<sup>10+</sup>
68
69测量后的组件布局信息。
70
71| 属性     | 属性类型   | 描述    |
72|--------|--------|-------|
73| width  | number | 测量后的宽。<br>单位:vp |
74| height | number | 测量后的高。<br>单位:vp |
75
76
77## SizeResult<sup>10+</sup>
78
79组件尺寸信息。
80
81| 属性     | 属性类型   | 描述    |
82|--------|--------|-------|
83| width  | number | 测量后的宽。<br>单位:vp |
84| height | number | 测量后的高。<br>单位:vp |
85
86> **说明:**
87>
88>- 自定义布局暂不支持LazyForEach写法。
89>- 使用builder形式的自定义布局创建,自定义组件的build()方法内只允许存在this.builder(),即示例的推荐用法。
90>- 父容器(自定义组件)上设置的尺寸信息,除aspectRatio之外,优先级小于onMeasureSize设置的尺寸信息。
91>- 子组件设置的位置信息,offset、position、markAnchor优先级大于onPlaceChildren设置的位置信息,其他位置设置属性不生效。
92>- 使用自定义布局方法时,需要同时调用onMeasureSize和onPlaceChildren方法,否则可能出现布局异常。
93
94```
95// xxx.ets
96@Entry
97@Component
98struct Index {
99  build() {
100    Column() {
101      CustomLayout({ builder: ColumnChildren })
102    }
103  }
104}
105
106@Builder
107function ColumnChildren() {
108  ForEach([1, 2, 3], (index: number) => { //暂不支持lazyForEach的写法
109    Text('S' + index)
110      .fontSize(30)
111      .width(100)
112      .height(100)
113      .borderWidth(2)
114      .offset({ x: 10, y: 20 })
115  })
116}
117
118@Component
119struct CustomLayout {
120  @Builder
121  doNothingBuilder() {
122  };
123
124  @BuilderParam builder: () => void = this.doNothingBuilder;
125  @State startSize: number = 100;
126  result: SizeResult = {
127    width: 0,
128    height: 0
129  };
130
131  onPlaceChildren(selfLayoutInfo: GeometryInfo, children: Array<Layoutable>, constraint: ConstraintSizeOptions) {
132    let startPos = 300;
133    children.forEach((child) => {
134      let pos = startPos - child.measureResult.height;
135      child.layout({ x: pos, y: pos })
136    })
137  }
138
139  onMeasureSize(selfLayoutInfo: GeometryInfo, children: Array<Measurable>, constraint: ConstraintSizeOptions) {
140    let size = 100;
141    children.forEach((child) => {
142      let result: MeasureResult = child.measure({ minHeight: size, minWidth: size, maxWidth: size, maxHeight: size })
143      size += result.width / 2
144      ;
145    })
146    this.result.width = 100;
147    this.result.height = 400;
148    return this.result;
149  }
150
151  build() {
152    this.builder()
153  }
154}
155```
156
157![custom_layout10.png](figures/custom_layout10.png)
158
159## onLayout<sup>(deprecated)</sup>
160
161onLayout?(children: Array&lt;LayoutChild&gt;, constraint: ConstraintSizeOptions): void
162
163ArkUI框架会在自定义组件布局时,将该自定义组件的子节点信息和自身的尺寸范围通过onLayout传递给该自定义组件。不允许在onLayout函数中改变状态变量。
164
165该接口从API version 9开始支持,从API version 10开始废弃,推荐使用[onPlaceChildren](#onplacechildren10)替代。
166
167**参数:**
168
169| 参数名        | 类型                                                         | 说明               |
170|------------|------------------------------------------------------------|------------------|
171| children   | Array&lt;[LayoutChild](#layoutchilddeprecated)&gt;                  | 子组件布局信息。         |
172| constraint | [ConstraintSizeOptions](ts-types.md#constraintsizeoptions) | 父组件constraint信息。 |
173
174## onMeasure<sup>(deprecated)</sup>
175
176onMeasure?(children: Array&lt;LayoutChild&gt;, constraint: ConstraintSizeOptions): void
177
178ArkUI框架会在自定义组件确定尺寸时,将该自定义组件的子节点信息和自身的尺寸范围通过onMeasure传递给该自定义组件。不允许在onMeasure函数中改变状态变量。
179
180该接口从API version 9开始支持,从API version 10开始废弃,推荐使用[onMeasureSize](#onmeasuresize10)替代。
181
182**参数:**
183
184| 参数名        | 类型                                                         | 说明               |
185|------------|------------------------------------------------------------|------------------|
186| children   | Array&lt;[LayoutChild](#layoutchilddeprecated)&gt;                  | 子组件布局信息。         |
187| constraint | [ConstraintSizeOptions](ts-types.md#constraintsizeoptions) | 父组件constraint信息。 |
188
189## LayoutChild<sup>(deprecated)</sup>
190
191子组件布局信息。
192
193从API version 9开始,从API version 10开始废弃,该接口支持在ArkTS卡片中使用。
194
195
196| 属性         | 属性类型                                                               | 描述                  |
197|------------|--------------------------------------------------------------------|---------------------|
198| name       | string                                                             | 子组件名称。              |
199| id         | string                                                             | 子组件id。              |
200| constraint | [ConstraintSizeOptions](ts-types.md#constraintsizeoptions)         | 子组件约束尺寸。            |
201| borderInfo | [LayoutBorderInfo](#layoutborderinfodeprecated)                             | 子组件border信息。        |
202| position   | [Position](ts-types.md#position8)                                   | 子组件位置坐标。            |
203| measure    | (childConstraint: [ConstraintSizeOptions](ts-types.md#constraintsizeoptions))&nbsp;=&gt;&nbsp;void                            | 调用此方法对子组件的尺寸范围进行限制。 |
204| layout     | (LayoutInfo: [LayoutInfo](#layoutinfodeprecated))&nbsp;=&gt;&nbsp;void | 调用此方法对子组件的位置信息进行限制。 |
205
206## LayoutBorderInfo<sup>(deprecated)</sup>
207
208子组件border信息。
209
210从API version 9开始,从API version 10开始废弃,该接口支持在ArkTS卡片中使用。
211
212| 属性          | 属性类型                                 | 描述                      |
213|-------------|--------------------------------------|-------------------------|
214| borderWidth | [EdgeWidths](ts-types.md#edgewidths9) | 边框宽度类型,用于描述组件边框不同方向的宽度。 |
215| margin      | [Margin](ts-types.md#margin)         | 外边距类型,用于描述组件不同方向的外边距。   |
216| padding     | [Padding](ts-types.md#padding)       | 内边距类型,用于描述组件不同方向的内边距。   |
217
218## LayoutInfo<sup>(deprecated)</sup>
219
220子组件layout信息。
221
222从API version 9开始,从API version 10开始废弃,该接口支持在ArkTS卡片中使用。
223
224| 属性         | 属性类型                                                       | 描述       |
225|------------|------------------------------------------------------------|----------|
226| position   | [Position](ts-types.md#position8)                           | 子组件位置坐标。 |
227| constraint | [ConstraintSizeOptions](ts-types.md#constraintsizeoptions) | 子组件约束尺寸。 |
228
229```ts
230// xxx.ets
231@Entry
232@Component
233struct Index {
234  build() {
235    Column() {
236      CustomLayout() {
237        ForEach([1, 2, 3], (index: number) => {
238          Text('Sub' + index)
239            .fontSize(30)
240            .borderWidth(2)
241        })
242      }
243    }
244  }
245}
246
247
248@Component
249struct CustomLayout {
250  @Builder
251  doNothingBuilder() {
252  };
253
254  @BuilderParam builder: () => void = this.doNothingBuilder;
255
256  onLayout(children: Array<LayoutChild>, constraint: ConstraintSizeOptions) {
257    let pos = 0;
258    children.forEach((child) => {
259      child.layout({ position: { x: pos, y: pos }, constraint: constraint })
260      pos += 70;
261    })
262  }
263
264  onMeasure(children: Array<LayoutChild>, constraint: ConstraintSizeOptions) {
265    let size = 100;
266    children.forEach((child) => {
267      child.measure({ minHeight: size, minWidth: size, maxWidth: size, maxHeight: size })
268      size += 50;
269    })
270  }
271
272  build() {
273    this.builder()
274  }
275}
276```
277
278![zh-cn_image_0000001511900496](figures/zh-cn_image_0000001511900496.png)