什么?看不懂鸿蒙Next中的锚点定位?一分钟教你学会相对布局

627 阅读3分钟

RelativeContainer是ArtUI中的相对布局,可以处理较为复杂的布局,也可以当做类似Stack的层叠布局使用。

为什么要使用这个容器?

这个容器能够减少组件的嵌套,相当于把之前的多层级结构拍平,使得UI渲染更快,性能更好。

作为层叠布局使用

具体的用法与Stack容器类似,在一个RelativeContainer容器中,后面加入的组件的层级要比前面加入的组件的层级要高。

复杂布局使用

一个RelativeContainer容器与其内部的子组件拥有下图所示的6个方向。

  • left, middle, right拥有HorizontalAlign.Start, HorizontalAlign.Center, HorizontalAlign.End这三对齐方式。
  • top, center, bottom拥有VerticalAlign.Top, VerticalAlign.Center, VerticalAlign.Bottom这三种对齐方式。

RelativeContainer容器中的子组件通过属性alignRules可以设置6个方向上的锚点以及该方向上的对齐方式。

alignRules: ({

left: {anchor: 锚点id (父容器的id值"container",或者组件通过属性id()设置的id值),align: 该方向对齐方式},

right: {anchor: 锚点id (父容器的id值"container",或者组件通过属性id()设置的id值),align: 该方向对齐方式}, })

下面以一段简单的示例代码来理解相对容器中锚点和对齐的使用。

RelativeContainer() {
  Row(){Text('row1')}.justifyContent(FlexAlign.Center)
    .width(100).height(100)
    .backgroundColor("#FF3333")
    .alignRules({
      top: {anchor: "__container__", align: VerticalAlign.Bottom},
      left: {anchor: "__container__", align: HorizontalAlign.Center}
    })
    .id("row1")
}
.width(300).height(300)
.border({width:2, color: "#6699FF"})

上面代码中具体的对齐过程如下:

  1. row1组件处理top方向的对齐。
  2. 首先找对锚点"container"即父容器。
  3. row1的top线与父容器的top线对齐。
  4. 处理VerticalAlign.Bottom对齐,row1的top线与父容器的bottom线对齐。

  1. 同样的,处理row1在left方向上的对齐。
  2. 首先找对锚点"container"即父容器。
  3. row1的left线与父容器的left线对齐。
  4. 处理HorizontalAlign.Center对齐,row1的left线与父容器的middle线对齐。

除了可以设置通过父容器为锚点,父容器中的其他组件也可设置为锚点,需要设置具体的值为该组件的id值。(可以通过属性id()为组件设置id)

下面介绍一个稍微复杂一点的示例。

RelativeContainer() {
  Row(){Text('row1')}.justifyContent(FlexAlign.Center)
  .width(100).height(100)
  .backgroundColor("#FF3333")
  .alignRules({
    top: {anchor: "__container__", align: VerticalAlign.Top},
    left: {anchor: "__container__", align: HorizontalAlign.Start}
  })
  .id("row1")

  Row(){Text('row2')}.justifyContent(FlexAlign.Center)
  .width(100).height(100)
  .backgroundColor("#FFCC00")
  .alignRules({
    top: {anchor: "__container__", align: VerticalAlign.Top},
    right: {anchor: "__container__", align: HorizontalAlign.End}
  })
  .id("row2")

  Row(){Text('row3')}.justifyContent(FlexAlign.Center)
  .height(100)
  .backgroundColor("#FF6633")
  .alignRules({
    top: {anchor: "row1", align: VerticalAlign.Bottom},
    left: {anchor: "row1", align: HorizontalAlign.Center},
    right: {anchor: "row2", align: HorizontalAlign.Start}
  })
  .id("row3")

}
.width(300).height(300)
.border({width:2, color: "#6699FF"})

row1和row2的对齐过程与第一个示例大致相同,这里不在阐述。这里具体讲解row3的对齐过程。

  1. row3处理top方向上的对齐。
  2. 首先找到锚点row1组件。
  3. row3的top线与row1的top线对齐
  4. 处理VerticalAlign.Bottom对齐,row3的top线与row1的bottom线对齐。

代码执行才执行到这一步

top: {anchor: "row1", align: VerticalAlign.Bottom},

并没有设置left和right方向。为什么row3的left线与row1的left线对齐,这是为什么?

实际上这里是相对容器的一个默认行为,如果没有对相对容器中的组件设置锚点对齐,那么其默认位置是在父容器的左上角。

  1. row3处理left方向上的对齐。
  2. 首先找到锚点row1组件。
  3. row3的left线和row1的left线对齐。
  4. 处理HorizontalAlign.Center对齐,row3的left线与row1的middle线对齐。

  1. row3处理right方向上的对齐。
  2. 首先找到row2组件。
  3. row3拉伸宽度,其right线与row2的right线对齐。
  4. 处理HorizontalAlign.Start对齐,row3的right线与row2的left线对齐。

在这里你会发现,我们并没有设置row3的宽度。通过锚点对齐可以实现组件的宽度自适应拉伸。