1# Flex
2
3以弹性方式布局子组件的容器组件。
4
5> **说明:**
6>
7> - 该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
8> - Flex组件在渲染时存在二次布局过程,因此在对性能有严格要求的场景下建议使用[Column](ts-container-column.md)、[Row](ts-container-row.md)代替。
9> - Flex组件主轴默认不设置时撑满父容器,[Column](ts-container-column.md)、[Row](ts-container-row.md)组件主轴不设置时默认是跟随子节点大小。
10> - 主轴长度可设置为auto使Flex自适应子组件布局,自适应时,Flex长度受constraintSize属性以及父容器传递的最大最小长度限制且constraintSize属性优先级更高。
11
12
13## 子组件
14
15可以包含子组件。
16
17
18## 接口
19
20Flex(value?: FlexOptions)
21
22标准Flex布局容器。具体指南请参考[弹性布局](../../../ui/arkts-layout-development-flex-layout.md)。
23
24**卡片能力:** 从API version 9开始,该接口支持在ArkTS卡片中使用。
25
26**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
27
28**系统能力:** SystemCapability.ArkUI.ArkUI.Full
29
30**参数:**
31
32| 参数名            | 类型        | 必填   | 说明                                     |
33| -------------- | ---------------------------------------- | ---- |  ---------------------------------------- |
34| value      | [FlexOptions](#flexoptions对象说明) | 否    |  弹性布局子组件参数。               |
35
36## FlexOptions对象说明
37
38**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
39
40**系统能力:** SystemCapability.ArkUI.ArkUI.Full
41
42| 名称            | 类型        | 必填   | 说明                                     |
43| -------------- | ---------------------------------------- | ---- |  ---------------------------------------- |
44| direction      | [FlexDirection](ts-appendix-enums.md#flexdirection) | 否     | 子组件在Flex容器上排列的方向,即主轴的方向。<br/>**默认值:** FlexDirection.Row<br/>**卡片能力:** 从API version 9开始,该接口支持在ArkTS卡片中使用。               |
45| wrap           | [FlexWrap](ts-appendix-enums.md#flexwrap) | 否     | Flex容器是单行/列还是多行/列排列。<br/>**默认值:** FlexWrap.NoWrap<br/>**说明:** <br/>在多行布局时,通过交叉轴方向,确认新行堆叠方向。<br/>**卡片能力:** 从API version 9开始,该接口支持在ArkTS卡片中使用。 |
46| justifyContent | [FlexAlign](ts-appendix-enums.md#flexalign) | 否     | 所有子组件在Flex容器主轴上的对齐格式。<br/>**默认值:** FlexAlign.Start<br/>**卡片能力:** 从API version 9开始,该接口支持在ArkTS卡片中使用。                    |
47| alignItems     | [ItemAlign](ts-appendix-enums.md#itemalign) | 否     | 所有子组件在Flex容器交叉轴上的对齐格式。 <br/>**默认值:** ItemAlign.Start<br/>**卡片能力:** 从API version 9开始,该接口支持在ArkTS卡片中使用。                 |
48| alignContent   | [FlexAlign](ts-appendix-enums.md#flexalign) | 否     | 交叉轴中有额外的空间时,多行内容的对齐方式。仅在wrap为Wrap或WrapReverse下生效。<br/>**默认值:** FlexAlign.Start<br/>**卡片能力:** 从API version 9开始,该接口支持在ArkTS卡片中使用。  |
49| space<sup>12+</sup>          | [FlexSpaceOptions<sup>12+</sup>](ts-container-flex.md#flexspaceoptions12) | 否   | 所有子组件在Flex容器主轴或交叉轴的space。<br/>**默认值:** {main:LengthMetrics.px(0), cross:LengthMetrics.px(0)} <br/>space为负数、百分比或者justifyContent设置为FlexAlign.SpaceBetweenFlexAlign.SpaceAroundFlexAlign.SpaceEvenly时不生效。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
50
51## FlexSpaceOptions<sup>12+</sup>
52
53**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
54
55**系统能力:** SystemCapability.ArkUI.ArkUI.Full
56
57| 名称          | 类型        |  只读     | 可选      | 说明      |
58| ----------- | --------- | ----------- | --------- |----------- |
59| main   | [LengthMetrics](../js-apis-arkui-graphics.md#lengthmetrics12)  | 否 | 是 | Flex容器主轴上的space。<br/> space: {main: LengthMetrics.unit(value)} |
60| cross  | [LengthMetrics](../js-apis-arkui-graphics.md#lengthmetrics12) | 否 | 是 | Flex容器交叉轴上的space。<br/> space: {cross: LengthMetrics.unit(value)} |
61
62## 示例
63
64### 示例1
65
66```ts
67// xxx.ets
68@Entry
69@Component
70struct FlexExample1 {
71  build() {
72    Column() {
73      Column({ space: 5 }) {
74        Text('direction:Row').fontSize(9).fontColor(0xCCCCCC).width('90%')
75        Flex({ direction: FlexDirection.Row }) { // 子组件在容器主轴上行布局
76          Text('1').width('20%').height(50).backgroundColor(0xF5DEB3)
77          Text('2').width('20%').height(50).backgroundColor(0xD2B48C)
78          Text('3').width('20%').height(50).backgroundColor(0xF5DEB3)
79          Text('4').width('20%').height(50).backgroundColor(0xD2B48C)
80        }
81        .height(70)
82        .width('90%')
83        .padding(10)
84        .backgroundColor(0xAFEEEE)
85
86        Text('direction:RowReverse').fontSize(9).fontColor(0xCCCCCC).width('90%')
87        Flex({ direction: FlexDirection.RowReverse }) { // 子组件在容器主轴上反向行布局
88          Text('1').width('20%').height(50).backgroundColor(0xF5DEB3)
89          Text('2').width('20%').height(50).backgroundColor(0xD2B48C)
90          Text('3').width('20%').height(50).backgroundColor(0xF5DEB3)
91          Text('4').width('20%').height(50).backgroundColor(0xD2B48C)
92        }
93        .height(70)
94        .width('90%')
95        .padding(10)
96        .backgroundColor(0xAFEEEE)
97
98        Text('direction:Column').fontSize(9).fontColor(0xCCCCCC).width('90%')
99        Flex({ direction: FlexDirection.Column }) { // 子组件在容器主轴上列布局
100          Text('1').width('100%').height(40).backgroundColor(0xF5DEB3)
101          Text('2').width('100%').height(40).backgroundColor(0xD2B48C)
102          Text('3').width('100%').height(40).backgroundColor(0xF5DEB3)
103          Text('4').width('100%').height(40).backgroundColor(0xD2B48C)
104        }
105        .height(160)
106        .width('90%')
107        .padding(10)
108        .backgroundColor(0xAFEEEE)
109
110        Text('direction:ColumnReverse').fontSize(9).fontColor(0xCCCCCC).width('90%')
111        Flex({ direction: FlexDirection.ColumnReverse }) { // 子组件在容器主轴上反向列布局
112          Text('1').width('100%').height(40).backgroundColor(0xF5DEB3)
113          Text('2').width('100%').height(40).backgroundColor(0xD2B48C)
114          Text('3').width('100%').height(40).backgroundColor(0xF5DEB3)
115          Text('4').width('100%').height(40).backgroundColor(0xD2B48C)
116        }
117        .height(160)
118        .width('90%')
119        .padding(10)
120        .backgroundColor(0xAFEEEE)
121      }.width('100%').margin({ top: 5 })
122    }.width('100%')
123  }
124}
125```
126
127![zh-cn_image_0000001219744189](figures/zh-cn_image_0000001219744189.PNG)
128
129### 示例2
130
131```ts
132// xxx.ets
133@Entry
134@Component
135struct FlexExample2 {
136  build() {
137    Column() {
138      Column({ space: 5 }) {
139        Text('Wrap').fontSize(9).fontColor(0xCCCCCC).width('90%')
140        Flex({ wrap: FlexWrap.Wrap }) { // 子组件多行布局
141          Text('1').width('50%').height(50).backgroundColor(0xF5DEB3)
142          Text('2').width('50%').height(50).backgroundColor(0xD2B48C)
143          Text('3').width('50%').height(50).backgroundColor(0xD2B48C)
144        }
145        .width('90%')
146        .padding(10)
147        .backgroundColor(0xAFEEEE)
148
149        Text('NoWrap').fontSize(9).fontColor(0xCCCCCC).width('90%')
150        Flex({ wrap: FlexWrap.NoWrap }) { // 子组件单行布局
151          Text('1').width('50%').height(50).backgroundColor(0xF5DEB3)
152          Text('2').width('50%').height(50).backgroundColor(0xD2B48C)
153          Text('3').width('50%').height(50).backgroundColor(0xF5DEB3)
154        }
155        .width('90%')
156        .padding(10)
157        .backgroundColor(0xAFEEEE)
158
159        Text('WrapReverse').fontSize(9).fontColor(0xCCCCCC).width('90%')
160        Flex({ wrap: FlexWrap.WrapReverse , direction:FlexDirection.Row }) { // 子组件反向多行布局
161          Text('1').width('50%').height(50).backgroundColor(0xF5DEB3)
162          Text('2').width('50%').height(50).backgroundColor(0xD2B48C)
163          Text('3').width('50%').height(50).backgroundColor(0xD2B48C)
164        }
165        .width('90%')
166        .height(120)
167        .padding(10)
168        .backgroundColor(0xAFEEEE)
169      }.width('100%').margin({ top: 5 })
170    }.width('100%')
171  }
172}
173```
174
175![zh-cn_image_0000001174264366](figures/zh-cn_image_0000001174264366.png)
176
177### 示例3
178
179```ts
180// xxx.ets
181@Component
182struct JustifyContentFlex {
183  justifyContent : number = 0;
184
185  build() {
186    Flex({ justifyContent: this.justifyContent }) {
187      Text('1').width('20%').height(50).backgroundColor(0xF5DEB3)
188      Text('2').width('20%').height(50).backgroundColor(0xD2B48C)
189      Text('3').width('20%').height(50).backgroundColor(0xF5DEB3)
190    }
191    .width('90%')
192    .padding(10)
193    .backgroundColor(0xAFEEEE)
194  }
195}
196
197@Entry
198@Component
199struct FlexExample3 {
200  build() {
201    Column() {
202      Column({ space: 5 }) {
203        Text('justifyContent:Start').fontSize(9).fontColor(0xCCCCCC).width('90%')
204        JustifyContentFlex({ justifyContent: FlexAlign.Start }) // 子组件在容器主轴上首端对齐
205
206        Text('justifyContent:Center').fontSize(9).fontColor(0xCCCCCC).width('90%')
207        JustifyContentFlex({ justifyContent: FlexAlign.Center }) // 子组件在容器主轴上居中对齐
208
209        Text('justifyContent:End').fontSize(9).fontColor(0xCCCCCC).width('90%')
210        JustifyContentFlex({ justifyContent: FlexAlign.End }) // 子组件在容器主轴上尾端对齐
211
212        Text('justifyContent:SpaceBetween').fontSize(9).fontColor(0xCCCCCC).width('90%')
213        JustifyContentFlex({ justifyContent: FlexAlign.SpaceBetween }) // 子组件在容器主轴上均分容器布局,第一个子组件与行首对齐,最后一个子组件与行尾对齐。
214
215        Text('justifyContent:SpaceAround').fontSize(9).fontColor(0xCCCCCC).width('90%')
216        JustifyContentFlex({ justifyContent: FlexAlign.SpaceAround }) // 子组件在容器主轴上均分容器布局,第一个子组件到行首的距离和最后一个子组件到行尾的距离是相邻子组件之间距离的一半。
217
218        Text('justifyContent:SpaceEvenly').fontSize(9).fontColor(0xCCCCCC).width('90%')
219        JustifyContentFlex({ justifyContent: FlexAlign.SpaceEvenly }) // 子组件在容器主轴上均分容器布局,子组件之间的距离与第一子组件到行首、最后一个子组件到行尾的距离相等
220      }.width('100%').margin({ top: 5 })
221    }.width('100%')
222  }
223}
224```
225
226![zh-cn_image_0000001174582854](figures/zh-cn_image_0000001174582854.PNG)
227
228### 示例4
229
230```ts
231// xxx.ets
232@Component
233struct AlignItemsFlex {
234  alignItems : number = 0;
235
236  build() {
237    Flex({ alignItems: this.alignItems }) {
238      Text('1').width('33%').height(30).backgroundColor(0xF5DEB3)
239      Text('2').width('33%').height(40).backgroundColor(0xD2B48C)
240      Text('3').width('33%').height(50).backgroundColor(0xF5DEB3)
241    }
242    .size({width: '90%', height: 80})
243    .padding(10)
244    .backgroundColor(0xAFEEEE)
245  }
246}
247
248@Entry
249@Component
250struct FlexExample4 {
251  build() {
252    Column() {
253      Column({ space: 5 }) {
254        Text('alignItems:Auto').fontSize(9).fontColor(0xCCCCCC).width('90%')
255        AlignItemsFlex({ alignItems: ItemAlign.Auto }) // 子组件在容器交叉轴上首部对齐
256
257        Text('alignItems:Start').fontSize(9).fontColor(0xCCCCCC).width('90%')
258        AlignItemsFlex({ alignItems: ItemAlign.Start }) // 子组件在容器交叉轴上首部对齐
259
260        Text('alignItems:Center').fontSize(9).fontColor(0xCCCCCC).width('90%')
261        AlignItemsFlex({ alignItems: ItemAlign.Center }) // 子组件在容器交叉轴上居中对齐
262
263        Text('alignItems:End').fontSize(9).fontColor(0xCCCCCC).width('90%')
264        AlignItemsFlex({ alignItems: ItemAlign.End }) // 子组件在容器交叉轴上尾部对齐
265
266        Text('alignItems:Stretch').fontSize(9).fontColor(0xCCCCCC).width('90%')
267        AlignItemsFlex({ alignItems: ItemAlign.Stretch }) // 子组件在容器交叉轴上拉伸填充
268
269        Text('alignItems:Baseline').fontSize(9).fontColor(0xCCCCCC).width('90%')
270        AlignItemsFlex({ alignItems: ItemAlign.Baseline }) // 子组件在容器交叉轴上与文本基线对齐
271      }.width('100%').margin({ top: 5 })
272    }.width('100%')
273  }
274}
275```
276
277![zh-cn_image_0000001174422904](figures/zh-cn_image_0000001174422904.png)
278
279### 示例5
280
281```ts
282// xxx.ets
283@Component
284struct AlignContentFlex {
285  alignContent: number = 0;
286
287  build() {
288    Flex({ wrap: FlexWrap.Wrap, alignContent: this.alignContent }) {
289      Text('1').width('50%').height(20).backgroundColor(0xF5DEB3)
290      Text('2').width('50%').height(20).backgroundColor(0xD2B48C)
291      Text('3').width('50%').height(20).backgroundColor(0xD2B48C)
292    }
293    .size({ width: '90%', height: 90 })
294    .padding(10)
295    .backgroundColor(0xAFEEEE)
296  }
297}
298
299@Entry
300@Component
301struct FlexExample5 {
302  build() {
303    Column() {
304      Column({ space: 5 }) {
305        Text('alignContent:Start').fontSize(9).fontColor(0xCCCCCC).width('90%')
306        AlignContentFlex({ alignContent: FlexAlign.Start }) // 多行布局下子组件首部对齐
307
308        Text('alignContent:Center').fontSize(9).fontColor(0xCCCCCC).width('90%')
309        AlignContentFlex({ alignContent: FlexAlign.Center }) // 多行布局下子组件居中对齐
310
311        Text('alignContent:End').fontSize(9).fontColor(0xCCCCCC).width('90%')
312        AlignContentFlex({ alignContent: FlexAlign.End }) // 多行布局下子组件尾部对齐
313
314        Text('alignContent:SpaceBetween').fontSize(9).fontColor(0xCCCCCC).width('90%')
315        AlignContentFlex({ alignContent: FlexAlign.SpaceBetween }) // 多行布局下第一行子组件与列首对齐,最后一行子组件与列尾对齐
316
317        Text('alignContent:SpaceAround').fontSize(9).fontColor(0xCCCCCC).width('90%')
318        AlignContentFlex({ alignContent: FlexAlign.SpaceAround }) // 多行布局下第一行子组件到列首的距离和最后一行子组件到列尾的距离是相邻行之间距离的一半
319
320        Text('alignContent:SpaceEvenly').fontSize(9).fontColor(0xCCCCCC).width('90%')
321        Flex({
322          wrap: FlexWrap.Wrap,
323          alignContent: FlexAlign.SpaceEvenly
324        }) { // 多行布局下相邻行之间的距离与第一行子组件到列首的距离、最后一行子组件到列尾的距离完全一样
325          Text('1').width('50%').height(20).backgroundColor(0xF5DEB3)
326          Text('2').width('50%').height(20).backgroundColor(0xD2B48C)
327          Text('3').width('50%').height(20).backgroundColor(0xF5DEB3)
328          Text('4').width('50%').height(20).backgroundColor(0xD2B48C)
329          Text('5').width('50%').height(20).backgroundColor(0xF5DEB3)
330        }
331        .size({ width: '90%', height: 100 })
332        .padding({ left: 10, right: 10 })
333        .backgroundColor(0xAFEEEE)
334      }.width('100%').margin({ top: 5 })
335    }.width('100%')
336  }
337}
338```
339
340![zh-cn_image_0000001174422906](figures/zh-cn_image_0000001174422906.PNG)
341
342### 示例6
343
344```ts
345import {LengthMetrics} from '@kit.ArkUI';
346
347@Entry
348@Component
349struct FlexExample2 {
350  build() {
351    Column() {
352      Column({ space: 5 }) {
353        Text('Wrap').fontSize(9).fontColor(0xCCCCCC).width('90%')
354        Flex({ wrap: FlexWrap.Wrap, space: {main: LengthMetrics.px(50), cross: LengthMetrics.px(50)} }) { // 子组件多行布局
355          Text('1').width('40%').height(50).backgroundColor(0xF5DEB3)
356          Text('2').width('40%').height(50).backgroundColor(0xD2B48C)
357          Text('3').width('40%').height(50).backgroundColor(0xD2B48C)
358        }
359        .width('90%')
360        .padding(10)
361        .backgroundColor(0xAFEEEE)
362
363        Text('NoWrap').fontSize(9).fontColor(0xCCCCCC).width('90%')
364        Flex({ wrap: FlexWrap.NoWrap, space: {main: LengthMetrics.px(50), cross: LengthMetrics.px(50)} }) { // 子组件单行布局
365          Text('1').width('50%').height(50).backgroundColor(0xF5DEB3)
366          Text('2').width('50%').height(50).backgroundColor(0xD2B48C)
367          Text('3').width('50%').height(50).backgroundColor(0xF5DEB3)
368        }
369        .width('90%')
370        .padding(10)
371        .backgroundColor(0xAFEEEE)
372
373        Text('WrapReverse').fontSize(9).fontColor(0xCCCCCC).width('90%')
374        Flex({ wrap: FlexWrap.WrapReverse, direction:FlexDirection.Row, space: {main: LengthMetrics.px(50), cross: LengthMetrics.px(50)} }) { // 子组件反向多行布局
375          Text('1').width('40%').height(50).backgroundColor(0xF5DEB3)
376          Text('2').width('40%').height(50).backgroundColor(0xD2B48C)
377          Text('3').width('40%').height(50).backgroundColor(0xD2B48C)
378        }
379        .width('90%')
380        .height(120)
381        .padding(10)
382        .backgroundColor(0xAFEEEE)
383      }.width('100%').margin({ top: 5 })
384    }.width('100%')
385  }
386}
387```
388
389![zh-cn_image_0000001174422907](figures/zh-cn_image_0000001174422907.PNG)
390
391### 示例7
392该示例实现了flex在宽度设置auto后可以自适应子组件布局的能力。
393```ts
394@Component
395struct Demo {
396  @Require @Prop text: string
397
398  build() {
399    Button() {
400      Flex() {
401        Image($r('sys.media.ohos_ic_public_voice'))
402          .width(16)
403          .height(16)
404
405        Row() {
406          Text(this.text)
407            .margin({
408              left: 6,
409              right: 6
410            })
411            .fontSize(14)
412            .maxLines(1)
413            .textOverflow({ overflow: TextOverflow.Ellipsis })
414        }
415
416        Image($r('sys.media.ohos_ic_public_sound'))
417          .width(16)
418          .height(16)
419      }.width("auto")
420    }
421    .backgroundColor(0xAFEEEE)
422    .height(36)
423    .padding({ left: 16, right: 16 })
424    .constraintSize({ maxWidth: 156 })
425    .width("auto")
426  }
427}
428
429@Entry
430@Component
431struct Index {
432  build() {
433    Column({ space: 12 }) {
434      Text("Width does not reach max length").fontSize(11).fontColor(0XCCCCCC).width("50%")
435      Demo({ text: "123" })
436      Text("Width reaches max length").fontSize(11).fontColor(0XCCCCCC).width("50%")
437      Demo({ text: "1234567890-1234567890-1234567890-1234567890" })
438    }
439  }
440}
441```
442
443![zh-cn_flexDemo_7](figures/zh-cn_flexDemo_7.png)
444