• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Custom Component Layout
2<!--Kit: ArkUI-->
3<!--Subsystem: ArkUI-->
4<!--Owner: @song-song-song-->
5<!--Designer: @lanshouren-->
6<!--Tester: @liuli0427-->
7<!--Adviser: @HelloCrease-->
8
9The custom layout of a custom component is used to lay out its child components through data calculation.
10
11> **NOTE**
12>
13> The initial APIs of this module are supported since API version 9. Newly added APIs will be marked with a superscript to indicate their earliest API version.
14>
15> A custom component is considered to have a custom layout when either of the **onMeasureSize** or **onPlaceChildren** methods is implemented. For complete layout control, implement both methods simultaneously. For details about the specifications, see the API descriptions for these methods.
16>
17> Since API version 20, when child components within a custom layout have their [LayoutPolicy](ts-types.md#layoutpolicy15) object's **fixAtIdealSize** property set to **true**, these components will ignore any layout constraints from their parent component. Instead, they will adhere to the size ranges explicitly defined by the developer in the custom layout implementation.
18>
19> Lazy loading (including [Repeat](../../../ui/state-management/arkts-new-rendering-control-repeat.md) and [LazyForEach](../../../ui/state-management/arkts-rendering-control-lazyforeach.md)) is not supported in custom layouts.
20
21## onMeasureSize<sup>10+</sup>
22
23onMeasureSize?(selfLayoutInfo: GeometryInfo, children: Array&lt;Measurable&gt;, constraint: ConstraintSizeOptions): SizeResult
24
25Invoked when the custom component needs to determine its size. Through this callback the component receives its layout information and size constraints from the ArkUI framework. State variables should not be changed in this callback.
26
27**Atomic service API**: This API can be used in atomic services since API version 11.
28
29**System capability**: SystemCapability.ArkUI.ArkUI.Full
30
31**Parameters**
32
33| Name        | Type                                                      | Mandatory|Description                                                        |
34| -------------- | ---------------------------------------------------------- | ---|------------------------------------------------------------ |
35| selfLayoutInfo | [GeometryInfo](#geometryinfo10)                            | Yes|Information about the component's computed layout properties after measurement.<br>**NOTE**<br>During the first layout, the component will use its own set attributes as the basis for layout.                                   |
36| children       | Array&lt;[Measurable](#measurable10)&gt;                   | Yes|Array containing layout information for all child components after measurement.<br>**NOTE**<br>When a child component does not have its layout information set, it retains the previous layout settings or, if no previous layout settings are available, stays at the default size of 0.|
37| constraint     | [ConstraintSizeOptions](ts-types.md#constraintsizeoptions) | Yes|Layout constraints applied to the component.                                      |
38
39**Return value**
40
41| Type                       | Description          |
42| --------------------------- | -------------- |
43| [SizeResult](#sizeresult10) | Component size information.|
44
45## onPlaceChildren<sup>10+</sup>
46
47onPlaceChildren?(selfLayoutInfo: GeometryInfo, children: Array&lt;Layoutable&gt;, constraint: ConstraintSizeOptions):void
48
49Invoked when the custom component needs to determine the positions of its child components. Through this callback the component receives its child component size constraints from the ArkUI framework. State variables should not be changed in this callback.
50
51**Atomic service API**: This API can be used in atomic services since API version 11.
52
53**System capability**: SystemCapability.ArkUI.ArkUI.Full
54
55**Parameters**
56
57| Name           | Type                                                        |Mandatory| Description              |
58|----------------|------------------------------------------------------------|---|------------------|
59| selfLayoutInfo | [GeometryInfo](#geometryinfo10)                            |Yes|Information about the component's computed layout properties after measurement.        |
60| children       | Array&lt;[Layoutable](#layoutable10)&gt;                   |Yes|Array containing layout information for all child components after measurement.        |
61| constraint     | [ConstraintSizeOptions](ts-types.md#constraintsizeoptions) |Yes|Layout constraints applied to the component.|
62
63**Example**
64
65See the [example for customizing a layout](#example).
66
67## GeometryInfo<sup>10+</sup>
68
69Provides the parent component layout information. Inherits from [SizeResult](#sizeresult10).
70
71**Atomic service API**: This API can be used in atomic services since API version 11.
72
73**System capability**: SystemCapability.ArkUI.ArkUI.Full
74
75| Name         | Type     |Read-Only|Optional| Description                 |
76|-------------|-----------|------|------|---------------------|
77| borderWidth | [EdgeWidth](ts-types.md#edgewidths9) |No|No| Border width of the parent component.<br>Unit: vp           |
78| margin      | [Margin](ts-types.md#margin)       | No|No|Margin of the parent component.<br>Unit: vp      |
79| padding     | [Padding](ts-types.md#padding)   |No|No| Padding of the parent component.<br>Unit: vp|
80
81## Layoutable<sup>10+</sup>
82
83Provides the child component layout information.
84
85**System capability**: SystemCapability.ArkUI.ArkUI.Full
86
87### Name
88
89| Name        | Type      | Read-Only|Optional|  Description                                                     |
90|--------------|---------------------------------- | ------|-----------------------------------------------------|---------------------|
91| measureResult| [MeasureResult](#measureresult10) |   No|No| Measurement result of the child component.<br>**Atomic service API**: This API can be used in atomic services since API version 11.<br>Unit: vp    |
92| uniqueId<sup>18+</sup>| number | No|No| Unique ID that the system assigns to the child component.<br>Value range: [0, +∞).<br>**Atomic service API**: This API can be used in atomic services since API version 18.|
93
94### layout
95
96layout(position: Position)
97
98Applies the specified position information to the child component.
99
100**Atomic service API**: This API can be used in atomic services since API version 11.
101
102**System capability**: SystemCapability.ArkUI.ArkUI.Full
103
104**Parameters**
105
106| Name        | Type                                                   | Mandatory                |Description        |
107|-----------------|---------------------------------------------------------|---------------------|-------------|
108|   position      | [Position](ts-types.md#position)                        | Yes                 |   Absolute position.  |
109
110### getMargin<sup>12+</sup>
111
112getMargin() : DirectionalEdgesT\<number>
113
114Obtains the margin values of the child component.
115
116**Atomic service API**: This API can be used in atomic services since API version 12.
117
118**System capability**: SystemCapability.ArkUI.ArkUI.Full
119
120**Return value**
121
122| Type                         | Description                                       |
123|------------------------------------|---------------------------------------------|
124| [DirectionalEdgesT&lt;number&gt;](#directionaledgestt12)  |  Margin values of the child component.  |
125
126 ### getPadding<sup>12+</sup>
127
128getPadding() : DirectionalEdgesT\<number>
129
130 Obtains the padding values of the child component.
131
132**Atomic service API**: This API can be used in atomic services since API version 12.
133
134**System capability**: SystemCapability.ArkUI.ArkUI.Full
135
136 **Return value**
137
138| Type                         | Description                                       |
139|------------------------------------|---------------------------------------------|
140| [DirectionalEdgesT&lt;number&gt;](#directionaledgestt12)  |  Padding values of the child component. |
141
142### getBorderWidth<sup>12+</sup>
143
144getBorderWidth() : DirectionalEdgesT\<number>
145
146Obtains the border widths of the child component.
147
148**Atomic service API**: This API can be used in atomic services since API version 12.
149
150**System capability**: SystemCapability.ArkUI.ArkUI.Full
151
152**Return value**
153
154| Type                         | Description                                       |
155|------------------------------------|---------------------------------------------|
156| [DirectionalEdgesT&lt;number&gt;](#directionaledgestt12)  |  Border widths of the child component. |
157
158## Measurable<sup>10+</sup>
159
160Provides the child component position information.
161
162**Atomic service API**: This API can be used in atomic services since API version 11.
163
164**System capability**: SystemCapability.ArkUI.ArkUI.Full
165
166### Name
167
168**Atomic service API**: This API can be used in atomic services since API version 18.
169
170**System capability**: SystemCapability.ArkUI.ArkUI.Full
171
172| Name        | Type      | Mandatory     |  Description                                                     |
173|--------------|---------------------------------- | -----------------------------------------------|---------------------|
174| uniqueId<sup>18+</sup>| number | No| Unique ID that the system assigns to the child component.|
175
176### measure
177
178 measure(constraint: ConstraintSizeOptions) : MeasureResult
179
180 Imposes size constraints on the child component.
181
182 **Atomic service API**: This API can be used in atomic services since API version 11.
183
184 **System capability**: SystemCapability.ArkUI.ArkUI.Full
185
186
187**Parameters**
188
189| Name        | Type                                                   | Mandatory                |Description        |
190|-----------------|---------------------------------------------------------|---------------------|-------------|
191|   constraint    | [ConstraintSizeOptions](ts-types.md#constraintsizeoptions)  | Yes           |   Size constraint. |
192
193**Return value**
194
195 | Type                              | Description                    |
196 |------------------------------------|-------------------------|
197 |[MeasureResult](#measureresult10)   | Provides the measurement result of the component.  |
198
199 ### getMargin<sup>12+</sup>
200
201 getMargin() : DirectionalEdgesT\<number\>
202
203 Obtains the margin values of the child component.
204
205**Atomic service API**: This API can be used in atomic services since API version 12.
206
207**System capability**: SystemCapability.ArkUI.ArkUI.Full
208
209**Return value**
210
211 | Type                              | Description                    |
212 |------------------------------------|-------------------------|
213 |[DirectionalEdgesT&lt;number&gt;](#directionaledgestt12)  | Margin values of the child component.  |
214
215### getPadding<sup>12+</sup>
216
217getPadding() : DirectionalEdgesT\<number\>
218
219Obtains the padding values of the child component.
220
221**Atomic service API**: This API can be used in atomic services since API version 12.
222
223**System capability**: SystemCapability.ArkUI.ArkUI.Full
224
225**Return value**
226
227 | Type                              | Description                    |
228 |------------------------------------|-------------------------|
229 |[DirectionalEdgesT&lt;number&gt;](#directionaledgestt12)  | Padding values of the child component.  |
230
231 ### getBorderWidth<sup>12+</sup>
232
233getBorderWidth() : DirectionalEdgesT\<number\>
234
235Obtains the border widths of the child component.
236
237**Atomic service API**: This API can be used in atomic services since API version 12.
238
239**System capability**: SystemCapability.ArkUI.ArkUI.Full
240
241**Return value**
242
243 | Type                              | Description                    |
244 |------------------------------------|-------------------------|
245 |[DirectionalEdgesT&lt;number&gt;](#directionaledgestt12)  | Border widths of the child component.|
246
247
248## MeasureResult<sup>10+</sup>
249
250Provides the measurement result of the component. This API inherits from [SizeResult] (#sizeresult10).
251
252**Atomic service API**: This API can be used in atomic services since API version 11.
253
254**System capability**: SystemCapability.ArkUI.ArkUI.Full
255
256## SizeResult<sup>10+</sup>
257
258Provides the component size information.
259
260**Atomic service API**: This API can be used in atomic services since API version 11.
261
262**System capability**: SystemCapability.ArkUI.ArkUI.Full
263
264| Name    | Type  |Read-Only|Optional| Description   |
265|--------|--------|------|------|-------|
266| width  | number | No|No|Width obtained from the measurement result.<br>Unit: vp|
267| height | number | No|No|Height obtained from the measurement result.<br>Unit: vp|
268
269## DirectionalEdgesT\<T><sup>12+</sup>
270
271Defines the directional edges.
272
273**Widget capability**: This API can be used in ArkTS widgets since API version 12.
274
275**Atomic service API**: This API can be used in atomic services since API version 12.
276
277**System capability**: SystemCapability.ArkUI.ArkUI.Full
278
279| Name  | Type|Read-Only|Optional| Description            |
280| ------ | ---- |------|------| ---------------- |
281| start   | T    |No|No| Start edge. It is the left edge if the direction is left-to-right and the right edge if the direction is right-to-left.|
282| end    | T    | No|No|End edge. It is the right edge if the direction is left-to-right and the left edge if the direction is right-to-left.|
283| top  | T    | No|No|Top edge.|
284| bottom | T    | No|No|Bottom edge.|
285
286> **NOTE**
287>
288>- The custom layout does not support the LazyForEach syntax.
289>- When a custom layout is created in builder mode, only **this.builder()** is allowed in the **build()** method of a custom component, as shown in the recommended usage in the example below.
290>- The size parameters of the parent component (custom component), except **aspectRatio**, are at a lower priority than those specified by **onMeasureSize**.
291>- The position parameters of the child component, except **offset**, **position**, and **markAnchor**, are at a lower priority than those specified by **onPlaceChildren**, and do not take effect.
292>- When using the custom layout method, you must call **onMeasureSize** and **onPlaceChildren** at the same time for the layout to display properly.
293
294## onLayout<sup>(deprecated)</sup>
295
296onLayout?(children: Array&lt;LayoutChild&gt;, constraint: ConstraintSizeOptions): void
297
298Invoked when the custom component lays out its child components. Through this callback the component receives its child component layout information and size constraint from the ArkUI framework. State variables should not be changed in this callback.
299
300This API is supported since API version 9 and deprecated since API version 10. You are advised to use [onPlaceChildren](#onplacechildren10) instead.
301
302**Widget capability**: This API can be used in ArkTS widgets since API version 9.
303
304**System capability**: SystemCapability.ArkUI.ArkUI.Full
305
306**Parameters**
307
308| Name       | Type                                                        | Mandatory|Description              |
309|------------|------------------------------------------------------------|------|------------------|
310| children   | Array&lt;[LayoutChild](#layoutchilddeprecated)&gt;                | Yes | Child component layout information.        |
311| constraint | [ConstraintSizeOptions](ts-types.md#constraintsizeoptions) | Yes |Size constraint of the parent component.|
312
313## onMeasure<sup>(deprecated)</sup>
314
315onMeasure?(children: Array&lt;LayoutChild&gt;, constraint: ConstraintSizeOptions): void
316
317Invoked when the custom component needs to determine its size. Through this callback the component receives its child component layout information and its own size constraints from the ArkUI framework. State variables should not be changed in this callback.
318
319This API is supported since API version 9 and deprecated since API version 10. You are advised to use [onMeasureSize](#onmeasuresize10) instead.
320
321**Widget capability**: This API can be used in ArkTS widgets since API version 9.
322
323**System capability**: SystemCapability.ArkUI.ArkUI.Full
324
325**Parameters**
326
327| Name       | Type                                                        |Mandatory| Description              |
328|------------|------------------------------------------------------------|------|------------------|
329| children   | Array&lt;[LayoutChild](#layoutchilddeprecated)&gt;                  | Yes |Child component layout information.        |
330| constraint | [ConstraintSizeOptions](ts-types.md#constraintsizeoptions) | Yes |Size constraint of the parent component.|
331
332## LayoutChild<sup>(deprecated)</sup>
333
334Child component layout information.
335
336This API is supported since API version 9 and deprecated since API version 10. It is supported in ArkTS widgets.
337
338**Widget capability**: This API can be used in ArkTS widgets since API version 9.
339
340**System capability**: SystemCapability.ArkUI.ArkUI.Full
341
342| Name      | Type                                                    | Read-Only|Optional|Description                                  |
343| ---------- | ------------------------------------------------------------ | ------|------|-------------------------------------- |
344| name       | string                                                       | No|No|Name of the child component.                          |
345| id         | string                                                       | No|No|ID of the child component.                            |
346| constraint | [ConstraintSizeOptions](ts-types.md#constraintsizeoptions)   | No|No|Constraint size of the child component.                      |
347| borderInfo | [LayoutBorderInfo](#layoutborderinfodeprecated)              | No|No|Provides the border information of the child component.                    |
348| position   | [Position](ts-types.md#position)                             | No|No|Position coordinates of the child component.                      |
349| measure    | (childConstraint: [ConstraintSizeOptions](ts-types.md#constraintsizeoptions)) =&gt; void |No|No| Method called to apply the size constraint to the child component.|
350| layout     | (LayoutInfo: [LayoutInfo](#layoutinfodeprecated)) =&gt; void | No|No|Method called to apply the specified position information to the child component.|
351
352## LayoutBorderInfo<sup>(deprecated)</sup>
353
354Provides the border information of the child component.
355
356This API is supported since API version 9 and deprecated since API version 10. It is supported in ArkTS widgets.
357
358**Widget capability**: This API can be used in ArkTS widgets since API version 9.
359
360**System capability**: SystemCapability.ArkUI.ArkUI.Full
361
362| Name         | Type                                | Read-Only|Optional|Description                     |
363|-------------|--------------------------------------|------|------|-------------------------|
364| borderWidth | [EdgeWidths](ts-types.md#edgewidths9) | No|No|Edge widths in different directions of the component.|
365| margin      | [Margin](ts-types.md#margin)         | No|No|Margin values in different directions of the component.  |
366| padding     | [Padding](ts-types.md#padding)       | No|No|Padding values in different directions of the component.  |
367
368## LayoutInfo<sup>(deprecated)</sup>
369
370Provides the layout information of the child component.
371
372This API is supported since API version 9 and deprecated since API version 10. It is supported in ArkTS widgets.
373
374**Widget capability**: This API can be used in ArkTS widgets since API version 9.
375
376**System capability**: SystemCapability.ArkUI.ArkUI.Full
377
378| Name      | Type                                                  | Read-Only|Optional|Description            |
379| ---------- | ---------------------------------------------------------- | ------|------|---------------- |
380| position   | [Position](ts-types.md#position)                           |No|No| Position coordinates of the child component.|
381| constraint | [ConstraintSizeOptions](ts-types.md#constraintsizeoptions) | No|No|Constraint size of the child component.|
382
383
384## Example
385
386### Example 1: Implementing a Custom Layout
387This example demonstrates how to implement a custom layout.
388```ts
389// xxx.ets
390@Entry
391@Component
392struct Index {
393  build() {
394    Column() {
395      CustomLayout({ builder: ColumnChildren })
396    }
397  }
398}
399
400@Builder
401function ColumnChildren() {
402  ForEach([1, 2, 3], (index: number) => { // LazyForEach is not supported.
403    Text('S' + index)
404      .fontSize(30)
405      .width(100)
406      .height(100)
407      .borderWidth(2)
408      .offset({ x: 10, y: 20 })
409  })
410}
411
412@Component
413struct CustomLayout {
414  @Builder
415  doNothingBuilder() {
416  };
417
418  @BuilderParam builder: () => void = this.doNothingBuilder;
419  @State startSize: number = 100;
420  result: SizeResult = {
421    width: 0,
422    height: 0
423  };
424
425  onPlaceChildren(selfLayoutInfo: GeometryInfo, children: Array<Layoutable>, constraint: ConstraintSizeOptions) {
426    let startPos = 300;
427    children.forEach((child) => {
428      let pos = startPos - child.measureResult.height;
429      child.layout({ x: pos, y: pos })
430    })
431  }
432
433  onMeasureSize(selfLayoutInfo: GeometryInfo, children: Array<Measurable>, constraint: ConstraintSizeOptions) {
434    let size = 100;
435    children.forEach((child) => {
436      let result: MeasureResult = child.measure({ minHeight: size, minWidth: size, maxWidth: size, maxHeight: size })
437      size += result.width / 2
438      ;
439    })
440    this.result.width = 100;
441    this.result.height = 400;
442    return this.result;
443  }
444
445  build() {
446    this.builder()
447  }
448}
449```
450
451![custom_layout10.png](figures/custom_layout10.png)
452
453### Example 2: Determining Whether to Participate in Layout Calculation
454This example shows how to determine whether a component participates in layout calculation based on its position.
455```ts
456// xxx.ets
457@Entry
458@Component
459struct Index {
460  build() {
461    Column() {
462      CustomLayout({ builder: ColumnChildren })
463    }
464    .justifyContent(FlexAlign.Center)
465    .width("100%")
466    .height("100%")
467  }
468}
469
470@Builder
471function ColumnChildren() {
472  ForEach([1, 2, 3], (item: number, index: number) => { // LazyForEach is not supported.
473    Text('S' + item)
474      .fontSize(20)
475      .width(60 + 10 * index)
476      .height(100)
477      .borderWidth(2)
478      .margin({ left:10 })
479      .padding(10)
480  })
481}
482
483@Component
484struct CustomLayout {
485  // Lay out only one row, and hide child components that are too large for the available space.
486  @Builder
487  doNothingBuilder() {
488  };
489
490  @BuilderParam builder: () => void = this.doNothingBuilder;
491  result: SizeResult = {
492    width: 0,
493    height: 0
494  };
495  overFlowIndex: number = -1;
496
497  onPlaceChildren(selfLayoutInfo: GeometryInfo, children: Array<Layoutable>, constraint: ConstraintSizeOptions) {
498    let currentX = 0;
499    let infinity = 100000;
500    if (this.overFlowIndex == -1) {
501      this.overFlowIndex = children.length;
502    }
503    for (let index = 0; index < children.length; ++index) {
504      let child = children[index];
505      if (index >= this.overFlowIndex) {
506        // Hide any child component that extends beyond the area of its parent component by placing it in a distant position.
507        child.layout({x: infinity, y: 0});
508        continue;
509      }
510      child.layout({ x: currentX, y: 0 })
511      let margin = child.getMargin();
512      currentX += child.measureResult.width + margin.start + margin.end;
513    }
514  }
515
516  onMeasureSize(selfLayoutInfo: GeometryInfo, children: Array<Measurable>, constraint: ConstraintSizeOptions) {
517    let width = 0;
518    let height = 0;
519    this.overFlowIndex = -1;
520    // Assume that the component width cannot exceed 200 vp or the maximum constraint.
521    let maxWidth = Math.min(200, constraint.maxWidth as number);
522    for (let index = 0; index < children.length; ++index) {
523      let child = children[index];
524      let childResult: MeasureResult = child.measure({
525          minHeight: constraint.minHeight,
526          minWidth: constraint.minWidth,
527          maxWidth: constraint.maxWidth,
528          maxHeight: constraint.maxHeight
529      })
530      let margin = child.getMargin();
531      let newWidth = width + childResult.width + margin.start + margin.end;
532      if (newWidth > maxWidth) {
533        // Record the index of the component that should not be laid out.
534        this.overFlowIndex = index;
535        break;
536      }
537      // Accumulate the width and height of the parent component.
538      width = newWidth;
539      height = Math.max(height, childResult.height + margin.top + margin.bottom);
540    }
541    this.result.width = width;
542    this.result.height = height;
543    return this.result;
544  }
545
546  build() {
547    this.builder()
548  }
549}
550```
551
552![custom_layout_demo2.png](figures/custom_layout_demo2.png)
553
554### Example 3: Obtaining the Child Component FrameNode and Setting Related Attributes
555This example shows how to obtain the [FrameNode](../js-apis-arkui-frameNode.md) of a child component using **uniqueId** and change its size and background color using the FrameNode API.
556```ts
557import { FrameNode, NodeController } from '@kit.ArkUI';
558@Entry
559@Component
560struct Index {
561  build() {
562    Column() {
563      CustomLayout()
564    }
565  }
566}
567
568class MyNodeController extends NodeController {
569  private rootNode: FrameNode | null = null;
570  makeNode(uiContext: UIContext): FrameNode | null {
571    this.rootNode = new FrameNode(uiContext)
572    return this.rootNode
573  }
574}
575
576@Component
577struct CustomLayout {
578  @Builder
579  childrenBuilder() {
580    ForEach([1, 2, 3], (index: number) => { // LazyForEach is not supported.
581      NodeContainer(new MyNodeController())
582    })
583  };
584
585  @BuilderParam builder: () => void = this.childrenBuilder;
586  result: SizeResult = {
587    width: 0,
588    height: 0
589  };
590
591  onPlaceChildren(selfLayoutInfo: GeometryInfo, children: Array<Layoutable>, constraint: ConstraintSizeOptions) {
592    let prev = 0;
593    children.forEach((child) => {
594      let pos = prev + 10;
595      prev = pos + child.measureResult.width
596      child.layout({ x: pos, y: 0 })
597    })
598  }
599
600  onMeasureSize(selfLayoutInfo: GeometryInfo, children: Array<Measurable>, constraint: ConstraintSizeOptions) {
601    let size = 100;
602    children.forEach((child) => {
603      console.log("child uniqueId: ", child.uniqueId)
604      const uiContext = this.getUIContext()
605      if (uiContext) {
606        let node: FrameNode | null = uiContext.getFrameNodeByUniqueId(child.uniqueId) // Obtain the FrameNode of the NodeContainer component.
607        if (node) {
608          node.getChild(0)!.commonAttribute.width(100)
609          node.getChild(0)!.commonAttribute.height(100)
610          node.getChild(0)!.commonAttribute.backgroundColor(Color.Pink) // Change the size and background color of the FrameNode.
611        }
612      }
613      child.measure({ minHeight: size, minWidth: size, maxWidth: size, maxHeight: size })
614    })
615    this.result.width = 320;
616    this.result.height = 100;
617    return this.result;
618  }
619
620  build() {
621    this.builder()
622  }
623}
624```
625![custom_layout_demo3.jpg](figures/custom_layout_demo3.jpg)
626
627### Example 4: Allowing the Child Component to Ignore Parent Component Size Constraints
628This example demonstrates how to use the **fixAtIdealSize** property of the [LayoutPolicy](ts-types.md#layoutpolicy15) object to allow the child component to ignore parent component size constraints.
629```ts
630@Entry
631@Component
632struct Index {
633  @Builder
634  ColumnChildrenText() {
635    Text("=====Text=====Text=====Text=====Text=====Text=====Text=====Text=====Text" )
636      .fontSize(16).fontColor(Color.Black)
637      .borderWidth(2).backgroundColor("#fff8dc")
638      .width(LayoutPolicy.fixAtIdealSize) // Set the child component's width to be unrestricted by the parent component.
639      .height(LayoutPolicy.fixAtIdealSize)  // Set the child component's height to be unrestricted by the parent component.
640  }
641
642  build() {
643    Column() {
644      Column() {
645        CustomLayoutText({ builder: this.ColumnChildrenText })
646          .backgroundColor("#f0ffff").borderRadius(20).margin(10)
647      }
648      .width(300)
649      .height(150)
650      .margin(10)
651      .backgroundColor(Color.Pink)
652    }
653    .width(350)
654    .height(680)
655    .margin(20)
656    .alignItems(HorizontalAlign.Center)
657  }
658}
659
660@Component
661struct CustomLayoutText {
662  @Builder
663  doSomethingBuilder() {
664  };
665
666  @BuilderParam
667  builder: () => void = this.doSomethingBuilder;
668  result: SizeResult = {
669    width: 0,
670    height: 0
671  };
672  // The custom component implements custom layout.
673  onPlaceChildren(selfLayoutInfo: GeometryInfo, children: Array<Layoutable>, constraint: ConstraintSizeOptions) {
674    let posY = 20;
675    children.forEach((child) => {
676      let posX = (selfLayoutInfo.width - child.measureResult.width) / 2;
677      child.layout({ x: posX, y: posY })
678      posY += child.measureResult.height + 30;
679    })
680  }
681
682  onMeasureSize(selfLayoutInfo: GeometryInfo, children: Array<Measurable>, constraint: ConstraintSizeOptions) {
683    children.forEach((child) => {
684      let result: MeasureResult = child.measure({ maxWidth: 335, maxHeight: 50 }) // Set constraints on the size of the child component of the custom component.
685    })
686    this.result.width = 200;
687    this.result.height = 130;
688    return this.result;
689  }
690
691  build() {
692    this.builder()
693  }
694}
695```
696![custom_layout_demo4.jpg](figures/custom_layout_demo4.jpg)
697
698### Example 5: Modifying the Layout Through layout
699This example shows how to modify a layout through **layout**.
700<!--deprecated_code_no_check-->
701```ts
702// xxx.ets
703@Entry
704@Component
705struct Index {
706  build() {
707    Column() {
708      CustomLayout() {
709        ForEach([1, 2, 3], (index: number) => {
710          Text('Sub' + index)
711            .fontSize(30)
712            .borderWidth(2)
713        })
714      }
715    }
716  }
717}
718
719
720@Component
721struct CustomLayout {
722  @Builder
723  doNothingBuilder() {
724  };
725
726  @BuilderParam builder: () => void = this.doNothingBuilder;
727
728  onLayout(children: Array<LayoutChild>, constraint: ConstraintSizeOptions) {
729    let pos = 0;
730    children.forEach((child) => {
731      child.layout({ position: { x: pos, y: pos }, constraint: constraint })
732      pos += 70;
733    })
734  }
735
736  onMeasure(children: Array<LayoutChild>, constraint: ConstraintSizeOptions) {
737    let size = 100;
738    children.forEach((child) => {
739      child.measure({ minHeight: size, minWidth: size, maxWidth: size, maxHeight: size })
740      size += 50;
741    })
742  }
743
744  build() {
745    this.builder()
746  }
747}
748```
749
750![en-us_image_0000001511900496](figures/en-us_image_0000001511900496.png)
751