ArkUI Flex 组件介绍与使用指南

什么是 Flex 组件?

Flex 是 ArkUI 中的弹性布局容器组件,它结合了 Column 和 Row 的特性,可以通过 direction 属性自由切换主轴方向,实现更灵活的布局。Flex 基于 CSS Flexbox 模型,提供了强大的布局能力。

Flex 的基本属性

  1. direction:设置主轴方向

    • FlexDirection.Row:水平排列(类似 Row)
    • FlexDirection.Column:垂直排列(类似 Column)
    • FlexDirection.RowReverse:反向水平排列
    • FlexDirection.ColumnReverse:反向垂直排列
  2. justifyContent:设置子组件在主轴方向的对齐方式

    • FlexAlign.Start(默认):起始端对齐
    • FlexAlign.Center:居中
    • FlexAlign.End:末端对齐
    • FlexAlign.SpaceBetween:均匀分布,首尾不留空
    • FlexAlign.SpaceAround:均匀分布,首尾留空
    • FlexAlign.SpaceEvenly:完全均匀分布
  3. alignItems:设置子组件在交叉轴方向的对齐方式

    • ItemAlign.Auto:默认值
    • ItemAlign.Start:起始端对齐
    • ItemAlign.Center:居中
    • ItemAlign.End:末端对齐
    • ItemAlign.Stretch:拉伸填满
    • ItemAlign.Baseline:基线对齐
  4. wrap:设置子组件换行方式

    • FlexWrap.NoWrap(默认):不换行
    • FlexWrap.Wrap:换行
    • FlexWrap.WrapReverse:反向换行

基本使用方法

@Entry
@Component
struct FlexExample {
  build() {
    Flex({ direction: FlexDirection.Row, wrap: FlexWrap.Wrap }) {
      ForEach([1, 2, 3, 4, 5, 6], (item) => {
        Text(`Item ${item}`)
          .width(100)
          .height(100)
          .backgroundColor('#f0f0f0')
          .margin(5)
          .textAlign(TextAlign.Center)
      })
    }
    .width('100%')
    .padding(10)
  }
}

高级用法

动态切换布局方向

@Entry
@Component
struct DynamicFlexExample {
  @State isColumn: boolean = false

  build() {
    Column() {
      Button('切换方向')
        .onClick(() => {
          this.isColumn = !this.isColumn
        })
        .margin(10)
      
      Flex({ direction: this.isColumn ? FlexDirection.Column : FlexDirection.Row }) {
        Text('Flex Item 1')
          .width(100)
          .height(80)
          .backgroundColor('#ffcccc')
        
        Text('Flex Item 2')
          .width(100)
          .height(80)
          .backgroundColor('#ccffcc')
        
        Text('Flex Item 3')
          .width(100)
          .height(80)
          .backgroundColor('#ccccff')
      }
      .width('100%')
      .margin(10)
      .border({ width: 1, color: Color.Black })
    }
  }
}

复杂对齐方式

Flex({
  direction: FlexDirection.Row,
  justifyContent: FlexAlign.SpaceBetween,
  alignItems: ItemAlign.Center
}) {
  Text('Start')
    .width(80)
    .height(60)
    .backgroundColor('#ffcccc')
  
  Text('Center')
    .width(80)
    .height(80)
    .backgroundColor('#ccffcc')
  
  Text('End')
    .width(80)
    .height(100)
    .backgroundColor('#ccccff')
}
.width('100%')
.height(200)
.padding(10)

Flex 子项属性

子组件可以设置以下属性:

  • flexGrow:定义子项的放大比例
  • flexShrink:定义子项的缩小比例
  • flexBasis:定义子项的基础尺寸
  • alignSelf:覆盖容器的 alignItems 设置
Flex({ direction: FlexDirection.Row }) {
  Text('Item 1')
    .width(50)
    .height(80)
    .flexGrow(1)  // 占据剩余空间的1/3
    .backgroundColor('#ffcccc')
  
  Text('Item 2')
    .width(50)
    .height(80)
    .flexGrow(2)  // 占据剩余空间的2/3
    .backgroundColor('#ccffcc')
  
  Text('Item 3')
    .width(50)
    .height(80)
    .alignSelf(ItemAlign.End)  // 单独设置对齐方式
    .backgroundColor('#ccccff')
}
.width('100%')
.height(100)
.padding(10)

实际应用示例

响应式网格布局

@Entry
@Component
struct ResponsiveGrid {
  @State itemCount: number = 8
  @State columns: number = 3

  build() {
    Column() {
      Row() {
        Button('增加列')
          .onClick(() => this.columns = Math.min(this.columns + 1, 5))
        Button('减少列')
          .onClick(() => this.columns = Math.max(this.columns - 1, 1))
        Button('添加项')
          .onClick(() => this.itemCount += 1)
      }
      .margin(10)
      
      Flex({ direction: FlexDirection.Row, wrap: FlexWrap.Wrap }) {
        ForEach(Array.from({ length: this.itemCount }), (_, index) => {
          Text(`Item ${index + 1}`)
            .width(`${100/this.columns}%`)
            .height(100)
            .backgroundColor(index % 2 === 0 ? '#f0f0f0' : '#e0e0e0')
            .textAlign(TextAlign.Center)
            .border({ width: 1, color: Color.Grey })
        })
      }
    }
  }
}

复杂卡片布局

@Entry
@Component
struct ComplexCard {
  build() {
    Flex({ direction: FlexDirection.Row }) {
      // 左侧图片
      Image('image_url')
        .width(120)
        .height(160)
        .objectFit(ImageFit.Cover)
      
      // 右侧内容
      Flex({ direction: FlexDirection.Column }) {
        Text('商品标题')
          .fontSize(18)
          .fontWeight(FontWeight.Bold)
          .margin({ bottom: 8 })
        
        Text('商品描述信息,这里可以放详细的商品描述内容...')
          .fontSize(14)
          .maxLines(2)
          .textOverflow({ overflow: TextOverflow.Ellipsis })
          .margin({ bottom: 8 })
        
        Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceBetween }) {
          Text('¥199.00')
            .fontSize(16)
            .fontColor('#f00')
          
          Button('购买')
            .width(80)
            .height(36)
        }
      }
      .flexGrow(1)
      .padding(10)
    }
    .width('90%')
    .margin(10)
    .borderRadius(8)
    .backgroundColor(Color.White)
    .shadow({ radius: 4, color: '#1a000000', offsetX: 1, offsetY: 1 })
  }
}

注意事项

  1. Flex 是 ArkUI 中最灵活的布局组件,适合复杂布局场景
  2. 合理使用 flexGrow/flexShrink 可以实现响应式布局
  3. 嵌套 Flex 时要注意性能影响,避免过度嵌套
  4. 在需要固定方向布局时,优先考虑使用 Row 或 Column 组件
  5. 使用 wrap 属性时,确保容器有足够的高度/宽度来显示多行/多列内容

Flex 组件提供了比 Row 和 Column 更强大的布局能力,特别适合需要动态调整布局方向或复杂对齐需求的场景。掌握 Flex 布局可以大幅提高 UI 开发的效率和灵活性。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐