HarmonyOS Next ArkUI--布局高级--【保姆级教程】

402 阅读6分钟

环境及工具

HarmonyOS 5.0.0 Release
DevEcoStudio
适用于HarmonyOS Next原生开发

1.线性布局

线性布局(LinearLayout)是开发中最常用的布局,通过线性容器 Row 和 Column 构建。Column容器内子元素按照垂直方向排列,Row容器内子元素按照水平方向排列。根据不同的排列方向,开发者可选择使用Row或Column容器创建线性布局。
图1 Column容器内子元素排列示意图
image.png

图2 Row容器内子元素排列示意图
image.png

1.1间距

1.1.1 Column容器内排列方向上的间距

在布局容器内,可以通过space属性设置排列方向上子元素的间距,使各子元素在排列方向上有等间距效果。

image.png

@Entry
@Component
struct Index {
  build() {
    Row({ space: 20}) {
      Text('子元素1')
        .width(100)
        .height(40)
        .backgroundColor(Color.Pink)
      Text('子元素2')
        .width(100)
        .height(40)
        .backgroundColor(Color.Orange)
      Text('子元素3')
        .width(100)
        .height(40)
        .backgroundColor(Color.Brown)
    }
  }
}

1.1.2Row容器内排列方向上的间距

image.png

@Entry
@Component
struct Index {
  build() {
    Column({ space: 20}) {
      Text('子元素1')
        .width(100)
        .height(40)
        .backgroundColor(Color.Pink)
      Text('子元素2')
        .width(100)
        .height(40)
        .backgroundColor(Color.Orange)
      Text('子元素3')
        .width(100)
        .height(40)
        .backgroundColor(Color.Brown)
    }
  }
}

1.2主轴对齐方式-justifyContent(FlexAlign.枚举值)

作用:设置容器中子元素在主轴上的对齐方式(作用到所有子元素身上)
属性:justifyContent()

Row(){}.justifyContent(FlexAlign.枚举值)

Column(){}.justifyContent(FlexAlign.枚举值)

参数:枚举FlexAlign

属性描述
Start首端对齐
Center居中对齐
End尾部对齐
Spacebetween两端对齐子元素之间间距相等
SpaceAround子元素两侧间距相等第一个元素到行首的距离和最后一个元素到行尾的距离是相邻元素之间距离的一半
SpaceEvenly相邻元素之间的距离、第一个元素与行首的间距、最后一个元素到行尾的间距都完全一样
Row容器表现:

image.png Column容器表现:

image.png


@Entry
@Component
struct Index {
  build() {
    Row() {
      Text('子元素1')
        .width(80)
        .height(40)
        .backgroundColor(Color.Pink)
      Text('子元素2')
        .width(80)
        .height(40)
        .backgroundColor(Color.Orange)
      Text('子元素3')
        .width(80)
        .height(40)
        .backgroundColor(Color.Brown)
    }
      .width('100%')
      .height(200)
      .backgroundColor('#ccc')
      // 主布局方向的对齐方式
      .justifyContent(FlexAlign.Center)
      // 两端对齐
      .justifyContent(FlexAlign.SpaceBetween)
  }
}

概念:

  • 布局主方向在线性布局中叫做布局主轴
  • 另外一条坐标轴叫做交叉轴

1.3交叉轴对齐方式-alignItems

以 Row 为例,主轴在水平方向,交叉轴在垂直方向

属性:alignItems()

参数:枚举类型VerticalAlign

注意:布局容器在交叉轴要有足够空间,否则无法生效

image.png

@Entry
@Component
struct Index {
  build() {
    Row() {
      Text('子元素1')
        .width(80)
        .height(40)
        .backgroundColor(Color.Pink)
      Text('子元素2')
        .width(80)
        .height(40)
        .backgroundColor(Color.Orange)
      Text('子元素3')
        .width(80)
        .height(40)
        .backgroundColor(Color.Brown)
    }
      .width('100%')
      .height(200)
      .backgroundColor('#ccc')
      // 顶部对齐
      .alignItems(VerticalAlign.Top)
      // 中部对齐
      .alignItems(VerticalAlign.Center)
      // 底部对齐
      .alignItems(VerticalAlign.Bottom)
  }
}

以 Column 为例,主轴在垂直方向,交叉轴在水平方向

属性:alignItems()

参数:枚举类型HorizontalAlign

注意:布局容器在交叉轴要有足够空间,否则无法生效

image.png

@Entry
@Component
struct Index {
  build() {
    Column() {
      Text('子元素1')
        .width(80)
        .height(40)
        .backgroundColor(Color.Pink)
      Text('子元素2')
        .width(80)
        .height(40)
        .backgroundColor(Color.Orange)
      Text('子元素3')
        .width(80)
        .height(40)
        .backgroundColor(Color.Brown)
    }
      .width('100%')
      .height(200)
      .backgroundColor('#ccc')
      // 顶部对齐
      .alignItems(HorizontalAlign.Top)
       // 中部对齐
      .alignItems(HorizontalAlign.Center)
      // 底部对齐
      .alignItems(HorizontalAlign.Bottom)
  }
}

1.5LayoutWeight-自适应缩放

父容器尺寸确定时,设置了 layoutWeight 属性的子元素与兄弟元素占主轴尺寸按照权重进行分配。

属性:layoutWeight()

参数:数字

image.png


@Entry
@Component
struct Index {
  build() {
    Column() {
      // 主轴方向:水平方向
      Row() {
        Text('左侧')
          .width(60)
          .height(30)
          .backgroundColor(Color.Blue)
        Text('中间')
          .height(30)
          .backgroundColor(Color.Red)
          .layoutWeight(1)
        Text('右侧 layoutWeight')
          .height(30)
          .backgroundColor(Color.Green)
          .layoutWeight(1)
      }
    }
  }
}

1.6 Coulumn-单个子元素交叉轴对齐方式

image.png

  • Column 主轴方向: 垂直方向
  • Column 交叉轴方向:水平方向

image.png

@Entry
@Component
struct Index {
  build() {
    Column() {
      Text('1')
        .width(100)
        .height(40)
        .fontWeight(900)
        .textAlign(TextAlign.Center)
        .backgroundColor(Color.Blue)
      Text('2')
        .width(100)
        .height(40)
        .fontWeight(900)
        .textAlign(TextAlign.Center)
        .backgroundColor(Color.Red)
          // 单个元素-交叉轴对齐方式
        // .alignSelf(ItemAlign.Start)     //顶部
        // .alignSelf(ItemAlign.Center)    //中间
        //.alignSelf(ItemAlign.End)        //底部
        .alignSelf(ItemAlign.Stretch)      //拉伸

      Text('3')
        .width(100)
        .height(40)
        .fontWeight(900)
        .textAlign(TextAlign.Center)
        .backgroundColor(Color.Yellow)
    }
    .width('100%')
    .height(300)
    .backgroundColor('#ccc')
    // 主轴对齐方式 -- 与Row写法一致
    .justifyContent(FlexAlign.SpaceBetween)
    // 交叉轴对齐方式(水平方向),默认居中
    .alignItems(HorizontalAlign.Start)
  }
}

1.7 Row-单个子元素交叉轴对齐方式

image.png

  • Row 主轴方向: 水平方向
  • Row 交叉轴方向:垂直方向

image.png

@Entry
@Component
struct Index {
  build() {
    Row() {
      Text('1')
        .width(100)
        .height(40)
        .fontWeight(900)
        .textAlign(TextAlign.Center)
        .backgroundColor(Color.Blue)
      Text('2')
        .width(100)
        .height(40)
        .fontWeight(900)
        .textAlign(TextAlign.Center)
        .backgroundColor(Color.Red)
          // 单个元素-交叉轴对齐方式
       //   .alignSelf(ItemAlign.Start)     //顶部
        //  .alignSelf(ItemAlign.Center)    //中间
        //  .alignSelf(ItemAlign.End)       //底部
            .alignSelf(ItemAlign.Stretch)   //拉伸

      Text('3')
        .width(100)
        .height(40)
        .fontWeight(900)
        .textAlign(TextAlign.Center)
        .backgroundColor(Color.Yellow)
    }
    .width('100%')
    .height(300)
    .backgroundColor('#ccc')
    // 主轴对齐方式 --
    .justifyContent(FlexAlign.SpaceBetween)
    // 交叉轴对齐方式(水平方向),默认居中
    .alignItems(VerticalAlign.Top)
  }
}

2.弹性布局

弹性布局是一种强大的布局模型,允许更高效和灵活地安排网页或应用界面中的元素。在鸿蒙操作系统(HarmonyOS)的开发中,弹性布局同样被支持,它允许开发者创建响应式的用户界面,这些界面可以根据不同的屏幕尺寸和方向自动调整。

概念:弹性布局提供更加有效的方式对容器中的子元素进行排列、对齐和分配剩余空间。常用于页面头部导航栏的均匀分布、页面框架的搭建、多行数据的排列等。 容器默认存在主轴与交叉轴,子元素默认沿主轴排列,子元素在主轴方向的尺寸称为主轴尺寸,在交叉轴方向的尺寸称为交叉轴尺寸。
主轴为水平方向的Flex容器示意图 

image.png 基本概念

  • 主轴:Flex组件布局方向的轴线,子元素默认沿着主轴排列。主轴开始的位置称为主轴起始点,结束位置称为主轴结束点。
  • 交叉轴:垂直于主轴方向的轴线。交叉轴开始的位置称为交叉轴起始点,结束位置称为交叉轴结束点。

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

image.png

2.1换行

示例

wrap 属性控制当子元素主轴尺寸之和大于容器主轴尺寸时,Flex 是单行布局还是多行布局。在多行布局时,通过交叉轴方向,确认新行排列方向。

参数:wrap

值:枚举 FlexWrap image.png

@Entry
@Component
struct Index {
  build() {
    Column() {
      Flex({wrap:FlexWrap.Wrap}) {
        Text()
          .width(80)
          .height(40)
          .backgroundColor(Color.Pink)
          .margin(5)
        Text()
          .width(80)
          .height(40)
          .backgroundColor(Color.Orange)
          .margin(5)
        Text()
          .width(80)
          .height(40)
          .backgroundColor(Color.Pink)
          .margin(5)
        Text()
          .width(80)
          .height(40)
          .backgroundColor(Color.Orange)
          .margin(5)
        Text()
          .width(80)
          .height(40)
          .backgroundColor(Color.Pink)
          .margin(5)
        Text()
          .width(80)
          .height(40)
          .backgroundColor(Color.Orange)
          .margin(5)
      }
        .width('100%')
        .height(200)
        .backgroundColor('#ccc')
    }
  }
}