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