ArkUI Flex:别再靠 margin 硬凑换行了

举报
蓝瘦的蜕变 发表于 2026/07/29 09:47:09 2026/07/29
【摘要】 今天我们用 Flex 处理几个 Row/Column 不太舒服的场景:自动换行、按比例分空间、单独调整某个子项对齐。 这篇不做响应式断点,也不把 Row/Column 拉出来长篇对比。我们只看 Flex 自己。 标签换行 标签数量不固定时,FlexWrap.Wrap 很好用: 你不用提前算一行放几个,也不用靠一堆手写

ArkUI Flex:别再靠 margin 硬凑换行了

今天我们用 Flex 处理几个 Row/Column 不太舒服的场景:自动换行、按比例分空间、单独调整某个子项对齐。

这篇不做响应式断点,也不把 Row/Column 拉出来长篇对比。我们只看 Flex 自己。

标签换行

标签数量不固定时,FlexWrap.Wrap 很好用:

Flex({ direction: FlexDirection.Row, wrap: FlexWrap.Wrap }) {
  ForEach(this.tags, (item: string) => {
    this.tagItem(item, '#2563EB')
  })
}

你不用提前算一行放几个,也不用靠一堆手写 margin 硬凑。容器宽度变了,标签会按空间自然换行。

flexGrow 分剩余空间

如果几个模块要按比例占宽:

Text('1').flexGrow(1)
Text('2').flexGrow(2)
Text('3').flexGrow(3)

这个例子里就是 1:2:3。实际业务里常见于统计卡片、操作区、底部按钮组。

alignSelf 单独处理一个子项

容器整体是顶部对齐,但某一项想居中或贴底,可以用 alignSelf

Text('Center')
  .alignSelf(ItemAlign.Center)

这比为了一个特殊项再包一层容器更清楚。

你做标签列表时,最烦的是换行、间距,还是某个标签特别长?可以把这个 Demo 的 tags 改成你自己的真实文案看看。

完整代码

@Entry
@Component
struct ArkUIFlexDemo {
  private tags: string[] = ['ArkUI', '布局', '换行', '间距', '对齐', '弹性', '卡片', '入口'];

  @Builder
  sectionTitle(title: string, desc: string) {
    Column({ space: 4 }) {
      Text(title)
        .width('100%')
        .fontSize(16)
        .fontWeight(700)
        .fontColor('#0F172A')

      Text(desc)
        .width('100%')
        .fontSize(13)
        .fontColor('#64748B')
        .lineHeight(20)
    }
    .width('100%')
    .alignItems(HorizontalAlign.Start)
  }

  @Builder
  tagItem(text: string, color: string) {
    Text(text)
      .height(38)
      .padding({ left: 14, right: 14 })
      .fontSize(13)
      .fontWeight(700)
      .fontColor(color)
      .textAlign(TextAlign.Center)
      .backgroundColor('#FFFFFF')
      .border({ width: 1, color: '#E2E8F0' })
      .borderRadius(8)
      .margin({ right: 8, bottom: 8 })
  }

  build() {
    Scroll() {
      Column({ space: 18 }) {
        Text('ArkUI Flex')
          .width('100%')
          .fontSize(24)
          .fontWeight(700)
          .fontColor('#0F172A')

        Text('别再靠 margin 硬凑换行了')
          .width('100%')
          .fontSize(22)
          .fontWeight(700)
          .fontColor('#111827')

        Text('Flex 适合处理“子项数量不固定、可能换行、需要分配剩余空间”的区域。这里只看 Flex 自己,不拿它和 Row/Column 长篇比较。')
          .width('100%')
          .fontSize(14)
          .fontColor('#64748B')
          .lineHeight(22)

        Column({ space: 12 }) {
          this.sectionTitle('wrap 让标签自己换行', '标签数量一多,硬写 margin 很快会乱。FlexWrap.Wrap 让子项按可用宽度自然换行。')

          Flex({ direction: FlexDirection.Row, wrap: FlexWrap.Wrap, justifyContent: FlexAlign.Start }) {
            ForEach(this.tags, (item: string, index: number) => {
              this.tagItem(item, index % 2 === 0 ? '#2563EB' : '#0F766E')
            }, (item: string) => item)
          }
          .width('100%')
          .padding({ top: 10, left: 10, right: 2, bottom: 2 })
          .backgroundColor('#FFFFFF')
          .border({ width: 1, color: '#DBEAFE' })
          .borderRadius(8)
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#EFF6FF')
        .borderRadius(8)

        Column({ space: 12 }) {
          this.sectionTitle('flexGrow 分配剩余空间', '当一行里有几个模块需要按比例变宽时,flexGrow 比手算百分比更好维护。')

          Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {
            Text('1')
              .height(58)
              .fontSize(18)
              .fontWeight(700)
              .fontColor('#FFFFFF')
              .textAlign(TextAlign.Center)
              .backgroundColor('#7C3AED')
              .borderRadius(8)
              .flexGrow(1)

            Text('2')
              .height(58)
              .fontSize(18)
              .fontWeight(700)
              .fontColor('#FFFFFF')
              .textAlign(TextAlign.Center)
              .backgroundColor('#C2410C')
              .borderRadius(8)
              .flexGrow(2)

            Text('3')
              .height(58)
              .fontSize(18)
              .fontWeight(700)
              .fontColor('#FFFFFF')
              .textAlign(TextAlign.Center)
              .backgroundColor('#0F766E')
              .borderRadius(8)
              .flexGrow(3)
          }
          .width('100%')
          .height(84)
          .padding(10)
          .backgroundColor('#FFFFFF')
          .border({ width: 1, color: '#DDD6FE' })
          .borderRadius(8)
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#F5F3FF')
        .borderRadius(8)

        Column({ space: 12 }) {
          this.sectionTitle('alignSelf 可以单独改一个子项', '容器整体按顶部对齐,但某个子项想居中或贴底,可以用 alignSelf 覆盖它自己的交叉轴位置。')

          Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Start, alignContent: FlexAlign.SpaceBetween }) {
            Text('Start')
              .width(76)
              .height(42)
              .fontSize(13)
              .fontWeight(700)
              .fontColor('#FFFFFF')
              .textAlign(TextAlign.Center)
              .backgroundColor('#2563EB')
              .borderRadius(8)

            Text('Center')
              .width(88)
              .height(42)
              .fontSize(13)
              .fontWeight(700)
              .fontColor('#FFFFFF')
              .textAlign(TextAlign.Center)
              .backgroundColor('#0F766E')
              .borderRadius(8)
              .alignSelf(ItemAlign.Center)

            Text('End')
              .width(76)
              .height(42)
              .fontSize(13)
              .fontWeight(700)
              .fontColor('#FFFFFF')
              .textAlign(TextAlign.Center)
              .backgroundColor('#C2410C')
              .borderRadius(8)
              .alignSelf(ItemAlign.End)
          }
          .width('100%')
          .height(120)
          .padding(10)
          .backgroundColor('#FFFFFF')
          .border({ width: 1, color: '#FED7AA' })
          .borderRadius(8)
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#FFF7ED')
        .borderRadius(8)
      }
      .width('100%')
      .padding(20)
      .alignItems(HorizontalAlign.Start)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#FFFFFF')
  }
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。