零基础学鸿蒙编程鸿蒙开发入门ArkTS/ArkUI实战

16、鸿蒙/布局/相对布局 (RelativeContainer

2024-07-14  本文已影响0人  圆梦人生

概述

在应用的开发过程中,经常需要设计复杂界面,此时涉及到多个相同或不同组件之间的嵌套。如果布局组件嵌套深度过深,或者嵌套组件数过多,会带来额外的开销。如果在布局的方式上进行优化,就可以有效的提升性能,减少时间开销。

RelativeContainer为采用相对布局的容器,支持容器内部的子元素设置相对位置关系,适用于界面复杂场景的情况,对多个子组件进行对齐和排列。子元素支持指定兄弟元素作为锚点,也支持指定父容器作为锚点,基于锚点做相对位置布局。下图是一个RelativeContainer的概念图,图中的虚线表示位置的依赖关系。


RelativeContainer.png

基本概念

设置依赖关系

RelativeContainer(){
      //
      Row(){}.backgroundColor(Color.Red).width(100).height(100)
      .id('row1')
      .alignRules({
        // anchor 以谁为锚地点定位,__container__为容器
        'top': { 'anchor': '__container__', 'align': VerticalAlign.Top },
        'left': { 'anchor': '__container__', 'align': HorizontalAlign.Start }
      })

      //
      Row(){}.backgroundColor(Color.Yellow).width(100).height(100)
      .alignRules({
        'top': { 'anchor': '__container__', 'align': VerticalAlign.Top },
        'right': { 'anchor': '__container__', 'align': HorizontalAlign.End }
      })
      .id('row2')

      Row(){}.backgroundColor(Color.Gray).width(100).height(100)
      .alignRules({
        // anchor 以谁为锚地点定位,row2为id为row2元素
        'top': { 'anchor': 'row2', 'align': VerticalAlign.Center },
        'right': { 'anchor': 'row2', 'align': HorizontalAlign.Start }
      })
      .id('row3')
}
RelativeContainer(){
      Row().backgroundColor(Color.Red).width(100).height(100).id('row1')
      Row().backgroundColor(Color.Yellow).width(100).height(100).id('row2')
        .alignRules({
          'top': { 'anchor': 'row1', 'align': VerticalAlign.Bottom },
          'right': { 'anchor': 'row1', 'align': HorizontalAlign.End }
        })
}
 RelativeContainer(){
      Row().backgroundColor(Color.Red).width(100).height(100).id('row1')
        .alignRules({
          top: {anchor: "__container__", align: VerticalAlign.Top},
          left: {anchor: "__container__", align: HorizontalAlign.Start}
        })
      Row().backgroundColor(Color.Yellow).width(100).height(100).id('row2')
        .alignRules({
          top: {anchor: "__container__", align: VerticalAlign.Top},
          right: {anchor: "__container__", align: HorizontalAlign.End},
          bottom: {anchor: "row1", align: VerticalAlign.Center},
        })
      Row().backgroundColor(Color.Gray).width(100).height(100).id('row3')
        .alignRules({
          top: {anchor: "row1", align: VerticalAlign.Bottom},
          left: {anchor: "row1", align: HorizontalAlign.Start},
          right: {anchor: "row2", align: HorizontalAlign.Start}
        })
}

设置相对于锚点的对齐位置

设置了锚点之后,可以通过align设置相对于锚点的对齐位置。
在水平方向上,对齐位置可以设置为HorizontalAlign.Start、HorizontalAlign.Center、HorizontalAlign.End。


HorizontalAlign.png

在竖直方向上,对齐位置可以设置为VerticalAlign.Top、VerticalAlign.Center、VerticalAlign.Bottom。


VerticalAlign.png

子组件位置偏移

子组件经过相对位置对齐后,位置可能还不是目标位置,开发者可根据需要进行额外偏移设置offset。

RelativeContainer(){
      Row().backgroundColor(Color.Red).width(100).height(100).id('row1')
        .alignRules({
          top: {anchor: "__container__", align: VerticalAlign.Top},
          left: {anchor: "__container__", align: HorizontalAlign.Start}
        })
      //
      Row().backgroundColor(Color.Yellow).width(100).height(100).id('row2')
        .alignRules({
          top: {anchor: "row1", align: VerticalAlign.Bottom},
          left: {anchor: "row1", align: HorizontalAlign.Start}
        })
        .offset( // 通过offset设置位置偏移
          {
            x: -40,
            y: 20
          }
        )
}

多种组件的对齐布局

Row、Column、Flex、Stack等多种布局组件,可按照RelativeContainer组件规则进行对其排布。

RelativeContainer(){
      // flex
      Row(){
        Text('广告')
      }.backgroundColor(Color.Red).height(100).width('100%').id('row1')
        .alignRules({
          top: {anchor: "__container__", align: VerticalAlign.Top},
          left: {anchor: "__container__", align: HorizontalAlign.Start}
        })
      // flex
      Flex(){
        Text('新闻').flexGrow(1).height(30).backgroundColor(Color.Red).textAlign(TextAlign.Center)
        Text('娱乐').flexGrow(1).height(30).backgroundColor(Color.Yellow).textAlign(TextAlign.Center)
        Text('汽车').flexGrow(1).height(30).backgroundColor(Color.Gray).textAlign(TextAlign.Center)
        Text('汽车').flexGrow(1).height(30).backgroundColor(Color.Gray).textAlign(TextAlign.Center)
      }
      .id('flex1')
      .alignRules({
        top: {anchor: "row1", align: VerticalAlign.Bottom},
        left: {anchor: "row1", align: HorizontalAlign.Start}
      }).offset({y: 10})
      // column
      Column(){
        Row(){
          Text('活动1').width('25%').height(100).backgroundColor(Color.Gray).textAlign(TextAlign.Center)
          Text('活动2').width('25%').height(100).backgroundColor(Color.Green).textAlign(TextAlign.Center)
          Text('活动2').width('25%').height(100).backgroundColor(Color.Gray).textAlign(TextAlign.Center)
          Text('活动2').width('25%').height(100).backgroundColor(Color.Green).textAlign(TextAlign.Center)
        }
      }.alignRules({
        top: {anchor: "flex1", align: VerticalAlign.Bottom},
        left: {anchor: "flex1", align: HorizontalAlign.Start}
      }).offset({y: 20})
      //
      Stack(){
        Text('Top')
      }.backgroundColor(Color.Blue).width(100).height(100)
      .alignRules({
        top: {anchor: "__container__", align: VerticalAlign.Center},
        left: {anchor: "__container__", align: HorizontalAlign.Center}
      })

}
多种布局.png
上一篇下一篇

猜你喜欢

热点阅读