找回密码
 立即注册
首页 业界区 业界 鸿蒙应用开发从入门到实战(二十三):一文搞懂ArkUI弹 ...

鸿蒙应用开发从入门到实战(二十三):一文搞懂ArkUI弹性布局

左优扬 3 天前
大家好,我是潘Sir,持续分享IT技术,帮你少走弯路。《鸿蒙应用开发从入门到项目实战》系列文章持续更新中,陆续更新AI+编程、企业级项目实战等原创内容、欢迎关注!
ArkUI提供了各种布局组件用于界面布局,本文研究使用Flex组件实现弹性布局。
一、概述

弹性布局(Flex)的效果类似于线性布局(Column/Row),也会使子元素呈线性排列,但是弹性布局在子元素的排列、对齐和剩余空间的分配等方面更加灵活。
二、参数

Flex组件的参数定义如下,下面逐一介绍每个属性
  1. Flex(value?: { direction?: FlexDirection, justifyContent?: FlexAlign, alignItems?: ItemAlign, wrap?: FlexWrap, alignContent?: FlexAlign })
复制代码
2.1 布局方向(direction)

direction用于设置Flex容器的布局方向,即子元素的排列方向,其类型FlexDirection为枚举类型,可选的枚举值如下
1.png

示例代码
pages/component/layout目录下新建flex目录,新建DirectionPage.ets文件
  1. @Entry
  2. @Component
  3. struct DirectionPage {
  4.   build() {
  5.     Column({ space: 50 }) {
  6.       Flex({ direction: FlexDirection.ColumnReverse }) {
  7.         Text('1')
  8.           .width(100)
  9.           .height(100)
  10.           .itemTextStyle4()
  11.         Text('2')
  12.           .width(100)
  13.           .height(100)
  14.           .itemTextStyle4()
  15.         Text('3')
  16.           .width(100)
  17.           .height(100)
  18.           .itemTextStyle4()
  19.       }
  20.       .height(350)
  21.       .width(350)
  22.       .flexStyle4()
  23.     }.width('100%')
  24.     .height('100%')
  25.     .justifyContent(FlexAlign.Center)
  26.   }
  27. }
  28. @Extend(Text) function itemTextStyle4() {
  29.   .textAlign(TextAlign.Center)
  30.   .fontColor(Color.White)
  31.   .fontSize(40)
  32.   .fontWeight(FontWeight.Bold)
  33.   .backgroundColor('#008a00')
  34.   .borderWidth(1)
  35. }
  36. @Extend(Flex) function flexStyle4() {
  37.   .backgroundColor('#f5f5f5')
  38.   .borderWidth(1)
  39. }
复制代码
Flex容器中也有主轴交叉轴两个概念,其中主轴方向与direction一致,交叉轴与主轴垂直,具体方向如下
2.png

2.2 主轴排列方式(justifyContent)

justifyContent参数的作用同Column/Row容器的justifyContent()完全相同,也是用于设置子元素在主轴方向的排列方式,其类型同样为FlexAlign,可选的枚举值如下
3.png

示例代码
pages/component/layout/flex目录,新建JustifyContentPage.ets文件
  1. @Entry
  2. @Component
  3. struct JustifyContentPage {
  4.   build() {
  5.     Column({ space: 50 }) {
  6.       Flex({
  7.         direction: FlexDirection.Row,
  8.         justifyContent: FlexAlign.Start
  9.       }) {
  10.         Text('1')
  11.           .width(50)
  12.           .height(50)
  13.           .itemTextStyle5()
  14.         Text('2')
  15.           .width(50)
  16.           .height(50)
  17.           .itemTextStyle5()
  18.         Text('3')
  19.           .width(50)
  20.           .height(50)
  21.           .itemTextStyle5()
  22.       }.height(50)
  23.       .width(300)
  24.       .flexStyle5()
  25.     }.width('100%')
  26.     .height('100%')
  27.     .justifyContent(FlexAlign.Center)
  28.   }
  29. }
  30. @Extend(Text) function itemTextStyle5() {
  31.   .textAlign(TextAlign.Center)
  32.   .fontColor(Color.White)
  33.   .fontSize(40)
  34.   .fontWeight(FontWeight.Bold)
  35.   .backgroundColor('#008a00')
  36.   .borderWidth(1)
  37. }
  38. @Extend(Flex) function flexStyle5() {
  39.   .backgroundColor('#f5f5f5')
  40.   .borderWidth(1)
  41. }
复制代码
2.3 交叉轴对齐方式(alignItems)

alignItems参数的作用同Column/Row容器的alignItems()相同,也是用于设置子元素在交叉轴的对齐方式。但该参数的类型与Column/Row容器的alignItems()方法不同,为ItemAlign,可选的枚举值有
4.png

示例代码
pages/component/layout/flex目录,新建AlignItemsFlexPage.ets文件
  1. @Entry
  2. @Component
  3. struct AlignItemsFlexPage {
  4.   build() {
  5.     Column({ space: 50 }) {
  6.       Flex({
  7.         direction: FlexDirection.Row,
  8.         alignItems: ItemAlign.Baseline
  9.       }) {
  10.         Text('Beyond')
  11.           .width(100)
  12.           .height(100)
  13.           .itemTextStyle6()
  14.         Text('章')
  15.           .width(100)
  16.           .height(200)
  17.           .itemTextStyle6()
  18.         Text('章')
  19.           .width(100)
  20.           .height(150)
  21.           .itemTextStyle6()
  22.       }.height(350)
  23.       .width(350)
  24.       .flexStyle6()
  25.     }.width('100%')
  26.     .height('100%')
  27.     .justifyContent(FlexAlign.Center)
  28.   }
  29. }
  30. @Extend(Text) function itemTextStyle6() {
  31.   .textAlign(TextAlign.Center)
  32.   .fontColor(Color.White)
  33.   .fontSize(40)
  34.   .fontWeight(FontWeight.Bold)
  35.   .backgroundColor('#008a00')
  36.   .borderWidth(1)
  37. }
  38. @Extend(Flex) function flexStyle6() {
  39.   .backgroundColor('#f5f5f5')
  40.   .borderWidth(1)
  41. }
复制代码
2.4 布局换行(列)(wrap)

默认情况下,Flex容器的子组件,都排在一条线(主轴)上。当子组件在主轴方向的尺寸之和大于Flex容器时,为适应容器尺寸,所有子组件的尺寸都会自动收缩。如果需要保持子组件的尺寸不收缩,也可选择令子组件换行(列)显示。
wrap属性的作用就是控制如何换行,该属性的类型FlexWrap为枚举类型,可选的枚举值如下
5.png

示例代码
pages/component/layout/flex目录,新建WrapPage.ets文件
  1. @Entry
  2. @Component
  3. struct WrapPage {
  4.   build() {
  5.     Column({ space: 50 }) {
  6.       Flex({
  7.         direction: FlexDirection.Row,
  8.         wrap: FlexWrap.WrapReverse
  9.       }) {
  10.         Text('1')
  11.           .width(100)
  12.           .height(100)
  13.           .itemTextStyle7()
  14.         Text('2')
  15.           .width(100)
  16.           .height(100)
  17.           .itemTextStyle7()
  18.         Text('3')
  19.           .width(100)
  20.           .height(100)
  21.           .itemTextStyle7()
  22.         Text('4')
  23.           .width(100)
  24.           .height(100)
  25.           .itemTextStyle7()
  26.         Text('5')
  27.           .width(100)
  28.           .height(100)
  29.           .itemTextStyle7()
  30.         Text('6')
  31.           .width(100)
  32.           .height(100)
  33.           .itemTextStyle7()
  34.       }.height(350)
  35.       .width(350)
  36.       .flexStyle7()
  37.     }.width('100%')
  38.     .height('100%')
  39.     .justifyContent(FlexAlign.Center)
  40.   }
  41. }
  42. @Extend(Text) function itemTextStyle7() {
  43.   .textAlign(TextAlign.Center)
  44.   .fontColor(Color.White)
  45.   .fontSize(40)
  46.   .fontWeight(FontWeight.Bold)
  47.   .backgroundColor('#008a00')
  48.   .borderWidth(1)
  49. }
  50. @Extend(Flex) function flexStyle7() {
  51.   .backgroundColor('#f5f5f5')
  52.   .borderWidth(1)
  53. }
复制代码
2.5 交叉轴多行排列方式(alignContent)

Flex容器中包含多行(列)时,可使用alignContent设置多行在交叉轴的排列方式,该属性的类型为FlexAlign,可选的枚举值如下
6.png

示例代码
pages/component/layout/flex目录,新建AlignContentPage.ets文件
  1. @Entry
  2. @Component
  3. struct AlignContentPage {
  4.   build() {
  5.     Column({ space: 50 }) {
  6.       Flex({
  7.         direction: FlexDirection.Row,
  8.         wrap: FlexWrap.Wrap,
  9.         alignContent: FlexAlign.SpaceAround,
  10.       }) {
  11.         Text('1')
  12.           .width(100)
  13.           .height(100)
  14.           .itemTextStyle8()
  15.         Text('2')
  16.           .width(100)
  17.           .height(100)
  18.           .itemTextStyle8()
  19.         Text('3')
  20.           .width(100)
  21.           .height(100)
  22.           .itemTextStyle8()
  23.         Text('4')
  24.           .width(100)
  25.           .height(100)
  26.           .itemTextStyle8()
  27.         Text('5')
  28.           .width(100)
  29.           .height(100)
  30.           .itemTextStyle8()
  31.         Text('6')
  32.           .width(100)
  33.           .height(100)
  34.           .itemTextStyle8()
  35.       }.height(350)
  36.       .width(350)
  37.       .flexStyle8()
  38.     }.width('100%')
  39.     .height('100%')
  40.     .justifyContent(FlexAlign.Center)
  41.   }
  42. }
  43. @Extend(Text) function itemTextStyle8() {
  44.   .textAlign(TextAlign.Center)
  45.   .fontColor(Color.White)
  46.   .fontSize(40)
  47.   .fontWeight(FontWeight.Bold)
  48.   .backgroundColor('#008a00')
  49.   .borderWidth(1)
  50. }
  51. @Extend(Flex) function flexStyle8() {
  52.   .backgroundColor('#f5f5f5')
  53.   .borderWidth(1)
  54. }
复制代码
三、子组件常用属性

3.1 交叉轴对齐(alignSelf)

Flex容器的子组件可以使用alignSelf()方法单独设置自己的交叉轴对齐方式,并且其优先级高于Flex容器alignItems。具体效果如下
说明:
alignSelf()的参数类型和alignItems()相同,均为ItemAlign枚举类型,且各枚举值的含义也完全相同。
代码
  1. Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Start }) {
  2.   Text('1')
  3.     .width(100)
  4.     .height(100)
  5.     .itemTextStyle()
  6.   Text('2')
  7.     .width(100)
  8.     .height(200)
  9.     .itemTextStyle()
  10.   Text('3')
  11.     .width(100)
  12.     .height(150)
  13.     .itemTextStyle()
  14.     .alignSelf(ItemAlign.End) //单独设置交叉轴对齐方式
  15. }.height(300)
  16. .width('95%')
  17. .flexStyle()
复制代码
效果
7.webp

示例代码
pages/component/layout/flex目录,新建AlignSelfPage.ets文件
  1. @Entry
  2. @Component
  3. struct AlignSelfPage {
  4.   build() {
  5.     Column({ space: 50 }) {
  6.       Flex({
  7.         direction: FlexDirection.Row,
  8.         alignItems: ItemAlign.Start
  9.       }) {
  10.         Text('1')
  11.           .width(100)
  12.           .height(100)
  13.           .itemTextStyle9()
  14.         Text('2')
  15.           .width(100)
  16.           .height(200)
  17.           .itemTextStyle9()
  18.         Text('3')
  19.           .width(100)
  20.           .height(150)
  21.           .itemTextStyle9()
  22.           .alignSelf(ItemAlign.End)
  23.       }.height(350)
  24.       .width(350)
  25.       .flexStyle9()
  26.     }.width('100%')
  27.     .height('100%')
  28.     .justifyContent(FlexAlign.Center)
  29.   }
  30. }
  31. @Extend(Text) function itemTextStyle9() {
  32.   .textAlign(TextAlign.Center)
  33.   .fontColor(Color.White)
  34.   .fontSize(40)
  35.   .fontWeight(FontWeight.Bold)
  36.   .backgroundColor('#008a00')
  37.   .borderWidth(1)
  38. }
  39. @Extend(Flex) function flexStyle9() {
  40.   .backgroundColor('#f5f5f5')
  41.   .borderWidth(1)
  42. }
复制代码
3.2 自适应伸缩

弹性布局的显著特点之一是子组件沿主轴方向的尺寸具有弹性,即子组件的大小能够随着Flex容器尺寸的变化而自动伸缩。这种弹性特性使得Flex布局能够使子组件更灵活地适应不同的屏幕尺寸和设备。和自适应伸缩的相关的属性有flexShrink、flexGrow和flexBasis,下面逐一介绍
3.2.1 flexShrink 压缩

flexShrink用于设置父容器空间不足时,子组件的压缩比例,尺寸的具体计算逻辑如下
代码
  1. //Flex容器主轴尺寸为240,子组件主轴尺寸之和为100*3=300
  2. Flex() {
  3.   //尺寸=100
  4.   Text('1')
  5.     .width(100)
  6.     .height(100)
  7.     .flexShrink(0) //不压缩
  8.   //主轴尺寸=100-(300-240)*(1/3)=80
  9.   Text('2')
  10.     .width(100)
  11.     .height(100)
  12.     .flexShrink(1) //压缩比例为1
  13.   //主轴尺寸=100-(300-240)*(2/3)=60
  14.   Text('3')
  15.     .width(100)
  16.     .height(100)
  17.     .flexShrink(2) //压缩比例为2
  18.   
  19. }.height(150)
  20. .width(240)
复制代码
效果
8.webp

示例代码
pages/component/layout/flex目录,新建FlexShrinkPage.ets文件
  1. @Entry
  2. @Component
  3. struct FlexShrinkPage {
  4.   build() {
  5.     Column({ space: 50 }) {
  6.       Flex({
  7.         direction: FlexDirection.Row,
  8.         alignItems: ItemAlign.Center
  9.       }) {
  10.         //尺寸=100
  11.         Text('1')
  12.           .width(100)
  13.           .height(100)
  14.           .itemTextStyle10()
  15.           .flexShrink(0) //不压缩
  16.         //主轴尺寸=100-(300-240)*(1/3)=80
  17.         Text('2')
  18.           .width(100)
  19.           .height(100)
  20.           .itemTextStyle10()
  21.           .flexShrink(1) //压缩比例为1
  22.         //主轴尺寸=100-(300-240)*(2/3)=60
  23.         Text('3')
  24.           .width(100)
  25.           .height(100)
  26.           .itemTextStyle10()
  27.           .flexShrink(2) //压缩比例为2
  28.       }.height(150)
  29.       .width(240)
  30.       .flexStyle10()
  31.     }.width('100%')
  32.     .height('100%')
  33.     .justifyContent(FlexAlign.Center)
  34.   }
  35. }
  36. @Extend(Text) function itemTextStyle10() {
  37.   .textAlign(TextAlign.Center)
  38.   .fontColor(Color.White)
  39.   .fontSize(40)
  40.   .fontWeight(FontWeight.Bold)
  41.   .backgroundColor('#008a00')
  42.   .borderWidth(1)
  43. }
  44. @Extend(Flex) function flexStyle10() {
  45.   .backgroundColor('#f5f5f5')
  46.   .borderWidth(1)
  47. }
复制代码
3.2.2 flexGrow 拉伸

flexGrow用于设置父容器空间充足时,组件瓜分剩余空间的比例,尺寸的具体计算逻辑如下
代码
  1. Flex() {
  2.   //尺寸=100
  3.   Text('1')
  4.     .width(100)
  5.     .height(100)
  6.     .flexGrow(0) //不拉伸
  7.   //主轴尺寸=100+(360-300)*(1/3)=120
  8.   Text('2')
  9.     .width(100)
  10.     .height(100)
  11.     .flexGrow(1) //拉伸比例为1
  12.   //主轴尺寸=100+(360-300)*(2/3)=140
  13.   Text('3')
  14.     .width(100)
  15.     .height(100)
  16.     .flexGrow(2) //拉伸比例为2
  17. }.height(150)
  18. .width(360)
复制代码
效果
9.webp

示例代码
pages/component/layout/flex目录,新建FlexGrowPage.ets文件
  1. @Entry
  2. @Component
  3. struct FlexGrowPage {
  4.   build() {
  5.     Column({ space: 50 }) {
  6.       Flex({
  7.         direction: FlexDirection.Row,
  8.         alignItems: ItemAlign.Center
  9.       }) {
  10.         //尺寸=100
  11.         Text('1')
  12.           .width(100)
  13.           .height(100)
  14.           .itemTextStyle11()
  15.           .flexGrow(0) //不拉伸
  16.         //主轴尺寸=100+(360-300)*(1/3)=120
  17.         Text('2')
  18.           .width(100)
  19.           .height(100)
  20.           .itemTextStyle11()
  21.           .flexGrow(1) //拉伸比例为1
  22.         //主轴尺寸=100+(360-300)*(2/3)=140
  23.         Text('3')
  24.           .width(100)
  25.           .height(100)
  26.           .itemTextStyle11()
  27.           .flexGrow(2) //拉伸比例为2
  28.       }.height(150)
  29.       .width(360)
  30.       .flexStyle11()
  31.     }.width('100%')
  32.     .height('100%')
  33.     .justifyContent(FlexAlign.Center)
  34.   }
  35. }
  36. @Extend(Text) function itemTextStyle11() {
  37.   .textAlign(TextAlign.Center)
  38.   .fontColor(Color.White)
  39.   .fontSize(40)
  40.   .fontWeight(FontWeight.Bold)
  41.   .backgroundColor('#008a00')
  42.   .borderWidth(1)
  43. }
  44. @Extend(Flex) function flexStyle11() {
  45.   .backgroundColor('#f5f5f5')
  46.   .borderWidth(1)
  47. }
复制代码
3.2.3 flexBasis

flexBasis用于设置子组件沿主轴方向的尺寸,相当于width或者height的作用。若设置了flexBasis,则以flexBasis为准,否则以widht或者height为准。
《鸿蒙应用开发从入门到项目实战》系列文章持续更新中,陆续更新AI+编程、企业级项目实战等原创内容,防止迷路,欢迎关注!

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册