目录

弹性布局 (Flex)

概述

弹性布局(Flex)提供更加有效的方式对容器中的子元素进行排列、对齐和分配剩余空间。常用于页面头部导航栏的均匀分布、页面框架的搭建、多行数据的排列等。

容器默认存在主轴与交叉轴,子元素默认沿主轴排列,子元素在主轴方向的尺寸称为主轴尺寸,在交叉轴方向的尺寸称为交叉轴尺寸。

图1 主轴为水平方向的Flex容器示意图

基本概念

布局方向

在弹性布局中,容器的子元素可以按照任意方向排列。通过设置FlexOptions的参数direction,可以决定主轴的方向,从而控制子元素的排列方向。

图2 弹性布局方向图

布局换行

弹性布局分为单行布局和多行布局。默认情况下,Flex容器中的子元素都排在一条线(又称“轴线”)上。wrap属性控制当子元素主轴尺寸之和大于容器主轴尺寸时,Flex是单行布局还是多行布局。在多行布局时,通过交叉轴方向,确认新行排列方向。

主轴对齐方式

通过justifyContent参数设置子元素在主轴方向的对齐方式。

交叉轴对齐方式

容器和子元素都可以设置交叉轴对齐方式,且子元素设置的对齐方式优先级较高。

[h2]容器组件设置交叉轴对齐

可以通过设置FlexOptions的参数alignItems,设置子元素在交叉轴的对齐方式。

[h2]子元素设置交叉轴对齐

子元素的alignSelf属性也可以设置子元素在父容器交叉轴的对齐方式,且会覆盖Flex布局容器中alignItems配置。如下例所示:

Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) { // 容器组件设置子元素居中
  Text('alignSelf Start').width('25%').height(80)
    .alignSelf(ItemAlign.Start)
    .backgroundColor('#F5DEB3')
  Text('alignSelf Baseline')
    .alignSelf(ItemAlign.Baseline)
    .width('25%')
    .height(80)
    .backgroundColor('#D2B48C')
  Text('alignSelf Baseline').width('25%').height(100)
    .backgroundColor('#F5DEB3')
    .alignSelf(ItemAlign.Baseline)
  Text('no alignSelf').width('25%').height(100)
    .backgroundColor('#D2B48C')
  Text('no alignSelf').width('25%').height(100)
    .backgroundColor('#F5DEB3')

}.width('90%').height(220).backgroundColor('#AFEEEE')

上例中,Flex容器中alignItems设置交叉轴子元素的对齐方式为居中,子元素自身设置了alignSelf属性的情况,覆盖父组件的alignItems值,表现为alignSelf的定义。

[h2]内容对齐

可以通过alignContent参数设置子元素各行在交叉轴剩余空间内的对齐方式,只在多行的Flex布局中生效,可选值有:

自适应拉伸

在弹性布局父组件尺寸过小时,通过子元素的以下属性设置其在父容器的占比,达到自适应布局。

场景示例

使用弹性布局,可以实现子元素沿水平方向排列,两端对齐,子元素间距平分,垂直方向上子元素居中的效果。

@Entry
@Component
struct FlexExample {
  build() {
    Column() {
      Column({ space: 5 }) {
        Flex({
          direction: FlexDirection.Row,
          wrap: FlexWrap.NoWrap,
          justifyContent: FlexAlign.SpaceBetween,
          alignItems: ItemAlign.Center
        }) {
          Text('1').width('30%').height(50).backgroundColor('#F5DEB3')
          Text('2').width('30%').height(50).backgroundColor('#D2B48C')
          Text('3').width('30%').height(50).backgroundColor('#F5DEB3')
        }
        .height(70)
        .width('90%')
        .backgroundColor('#AFEEEE')
      }.width('100%').margin({ top: 5 })
    }.width('100%')
  }
}