鸿蒙系列之一相对布局(RelativeContainer)

341 阅读4分钟
  1. 对布局组件,用于复杂场景中元素对齐的布局。
  • RelativeContainer就是采用相对布局的容器,支持容器内部的子元素设置相对位置关系。子元素支持指定兄弟元素作为锚点,也支持指定父容器作为锚点,基于锚点做相对位置布局。下图是一个 RelativeContainer的概念图,图中的虚线表示位置的依赖关系。

image.png

  1. 规则说明
  • 容器内子组件区分水平方向,垂直方向:
    • 水平方向为left,middle,right,对应容器的HorizontalAlign.Start,HorizontalAlign.Center,HorizontalAlign.End。
    • 垂直方向为top,center,bottom,对应容器的VerticalAlign.Top,VerticalAlign.Center,VerticalAlign.Bottom。
  • 子组件可以将容器或者其他子组件设为锚点:
    • 参与相对布局的容器内组件必须设置id,不设置id的组件不显示,RelativeContainer容器的固定id为__container__。
    • 此子组件某一方向上的三个位置可以将容器或其他子组件的同方向三个位置为锚点,同方向上两个以上位置设置锚点以后会跳过第三个。
    • 前端页面设置的子组件尺寸大小不会受到相对布局规则的影响。子组件某个方向上设置两个或以上alignRules时不建议设置此方向尺寸大小。
    • 对齐后需要额外偏移可设置offset。
  • 特殊情况
    • 互相依赖,环形依赖时容器内子组件全部不绘制。
    • 同方向上两个以上位置设置锚点但锚点位置逆序时此子组件大小为0,即不绘制。
    • 容器不设置宽高时,容器与容器内子组件不绘制。
  1. RelativeContainer的基本使用演示
@Entry
@Component
struct Index {
  @State message: string = 'Hello World';

  build() {
    Column(){
      //RelativeContainer必须包含子元素
      //RelativeContainer 里面的子元素必须配置id
      //RelativeContainer 固定id __container__
      //子元素id不能重复
      RelativeContainer(){
          Text('1')
            .width(100)
            .height(100)
            .fontSize(30)
            .fontColor(Color.White)
            .textAlign(TextAlign.Center)
            .backgroundColor(Color.Blue)
            .id('text1')
            .alignRules({
              right:{
                anchor:"__container__",
                align:HorizontalAlign.End
              }
            })
        Text('5')
          .width(100)
          .height(100)
          .fontSize(30)
          .fontColor(Color.White)
          .textAlign(TextAlign.Center)
          .backgroundColor(Color.Blue)
          .id('text5')
          .alignRules({
            right:{
              anchor:"text1",
              align:HorizontalAlign.Start
            },
            top: {
              anchor:"text1",
              align:VerticalAlign.Bottom
            }
          })

        Text('2')
          .width(100)
          .height(100)
          .fontSize(30)
          .fontColor(Color.White)
          .textAlign(TextAlign.Center)
          .backgroundColor(Color.Blue)
          .id('text2')
          .alignRules({
            left:{
              anchor:"__container__",
              align:HorizontalAlign.Start
            }
          })

        Text('3')
          .width(100)
          .height(100)
          .fontSize(30)
          .fontColor(Color.White)
          .textAlign(TextAlign.Center)
          .backgroundColor(Color.Blue)
          .id('text3')
          .alignRules({
            left:{
              anchor:"__container__",
              align:HorizontalAlign.Start
            },
            bottom:{
              anchor:"__container__",
              align:VerticalAlign.Bottom
            }
          })

        Text('4')
          .width(100)
          .height(100)
          .fontSize(30)
          .fontColor(Color.White)
          .textAlign(TextAlign.Center)
          .backgroundColor(Color.Blue)
          .id('text4')
          .alignRules({
            right:{
              anchor:"__container__",
              align:HorizontalAlign.End
            },
            bottom:{
              anchor:"__container__",
              align:VerticalAlign.Bottom
            }
          })

        Text('6')
          .width(100)
          .height(100)
          .fontSize(30)
          .fontColor(Color.White)
          .textAlign(TextAlign.Center)
          .backgroundColor(Color.Red)
          .id('text6')
          .alignRules({
            left:{
              anchor:"__container__",
              align:HorizontalAlign.Start
            },
            center:{
              anchor:"__container__",
              align:VerticalAlign.Center
            }

          })

        Text('7')
          .width(100)
          .height(100)
          .fontSize(30)
          .fontColor(Color.White)
          .textAlign(TextAlign.Center)
          .backgroundColor(Color.Red)
          .id('text7')
          .alignRules({
            right:{
              anchor:"__container__",
              align:HorizontalAlign.End
            },
            center:{
              anchor:"__container__",
              align:VerticalAlign.Center
            }

          })
          .offset({x:10})//设置偏移量

      }
      .width(300)
      .height(300)
      .border({
        color:Color.Gray,
        width:2

      })
    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.Center)
  }
}

image.png

3.练习一

Column(){
  RelativeContainer(){
    Text('1')
      .width(100)
      .height(100)
      .fontColor(Color.White)
      .fontSize(30)
      .textAlign(TextAlign.Center)
      .backgroundColor(Color.Red)
      .id('text1')
      .alignRules(
        {
          middle:{
            anchor:"__container__",
            align:HorizontalAlign.Center
          }
        }
      )

    Text('2')
      .width(100)
      .height(100)
      .fontColor(Color.White)
      .fontSize(30)
      .textAlign(TextAlign.Center)
      .backgroundColor(Color.Blue)
      .id('text2')
      .alignRules(
        {
          middle:{
            anchor:"__container__",
            align:HorizontalAlign.Center
          },
          center:{
            anchor:"__container__",
            align:VerticalAlign.Center
          }
        }
      )

    Text('3')
      .width(100)
      .height(100)
      .fontColor(Color.White)
      .fontSize(30)
      .textAlign(TextAlign.Center)
      .backgroundColor(Color.Red)
      .id('text3')
      .alignRules(
        {
          bottom:{
            anchor:"__container__",
            align:VerticalAlign.Bottom
          },
          middle:{
            anchor:"__container__",
            align:HorizontalAlign.Center
          }
        }
      )

    Text('4')
      .width(100)
      .height(100)
      .fontColor(Color.White)
      .fontSize(30)
      .textAlign(TextAlign.Center)
      .backgroundColor(Color.Red)
      .id('text4')
      .alignRules(
        {
          top:{
            anchor:"text2",
            align:VerticalAlign.Top
          },
          right:{
            anchor:"text2",
            align:HorizontalAlign.Start
          }
        }
      )

    Text('5')
      .width(100)
      .height(100)
      .fontColor(Color.White)
      .fontSize(30)
      .textAlign(TextAlign.Center)
      .backgroundColor(Color.Red)
      .id('text5')
      .alignRules(
        {
          top:{
            anchor:"text2",
            align:VerticalAlign.Top
          },
          left:{
            anchor:"text2",
            align:HorizontalAlign.End
          }
        }
      )

  }
  .width(300)
  .height(300)
  .borderWidth(1)
  .borderColor(Color.Gray)

}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)

image.png

  1. 练习2
Column(){
  Stack({alignContent:Alignment.BottomEnd}){
    List({space:10}){
      ForEach([1,2,3,4,5,6,7,8,9,10],(item,index)=>{
        ListItem(){
          Text(`${item}`)
            .textAlign(TextAlign.Center)
            .fontSize(30)
            .fontColor(Color.White)
            .width('100%')
            .height(50)
            .backgroundColor(Color.Gray)
        }
      },item=>item)
    }
    .height('100%')
    .onClick(()=>{
      this.flag=false;
    })

    RelativeContainer(){
      Button(){
        Text('+')
          .fontSize(30)
          .fontColor(Color.White)
      }
      .width(60)
      .height(60)
      .id('btn1')
      .alignRules({
        right:{anchor:"__container__",align:HorizontalAlign.End},
        bottom:{anchor:"__container__",align:VerticalAlign.Bottom}
      })
      .offset({y:-10,x:-10})
      .onClick(()=>{
        this.flag=!this.flag
      })



      if (this.flag){
        Button(){
          Text('A')
            .fontSize(30)
            .fontColor(Color.White)
        }
        .width(60)
        .height(60)
        .backgroundColor(Color.Red)
        .id('btnA')
        .alignRules({
          right:{anchor:"btn1",align:HorizontalAlign.End},
          bottom:{anchor:"btn1",align:VerticalAlign.Top}
        })
        .offset({y:-30,x:-10})

        Button(){
          Text('B')
            .fontSize(30)
            .fontColor(Color.White)
        }
        .width(60)
        .height(60)
        .backgroundColor(Color.Yellow)
        .id('btnB')
        .alignRules({
          right:{anchor:"btn1",align:HorizontalAlign.Start},
          bottom:{anchor:"btn1",align:VerticalAlign.Bottom}
        })
        .offset({x:-30,y:-10})

        Button(){
          Text('C')
            .fontSize(30)
            .fontColor(Color.White)
        }
        .width(60)
        .height(60)
        .backgroundColor(Color.Orange)
        .id('btnC')
        .alignRules({
          right:{anchor:"btnB",align:HorizontalAlign.End},
          bottom:{anchor:"btnB",align:VerticalAlign.Top}
        })
        .offset({x:-30,y:-25})
      }



    }.width(160)
    .height(160)

  }

}
.height('100%')
.width('100%')

image.png