層疊布局(Stack)用于在屏幕上預(yù)留一塊區(qū)域來顯示組件中的元素,提供元素可以重疊的布局。層疊布局通過Stack容器組件實(shí)現(xiàn)位置的固定定位與層疊,容器中的子元素依次入棧,后一個(gè)子元素覆蓋前一個(gè)子元素,子元素可以疊加,也可以設(shè)置位置。
相對(duì)布局(RelativeContainer)是一種采用相對(duì)布局的容器,支持容器內(nèi)部的子元素設(shè)置相對(duì)位置關(guān)系,適用于處理界面復(fù)雜的場景,對(duì)多個(gè)子元素進(jìn)行對(duì)齊和排列。子元素可以指定兄弟元素或父容器作為錨點(diǎn),基于錨點(diǎn)進(jìn)行相對(duì)位置布局。
實(shí)際使用中,當(dāng)一個(gè)Stack中添加多個(gè)子組件時(shí),并不能分別設(shè)置每個(gè)子組件的對(duì)齊方式,只能保持一個(gè)對(duì)齊方式,有一定的局限性。
因此我們可以使用RelativeContainer,通過設(shè)置子組件的對(duì)齊方式,不僅可以實(shí)現(xiàn)層疊顯示,還可以分別設(shè)置多個(gè)子組件,減少布局組件嵌套,可以有效的提升性能,減少時(shí)間開銷
RelativeContainer的子組件需要設(shè)置alignRules來設(shè)置子組件的相對(duì)位置,我對(duì)子組件相對(duì)父布局的位置做了一個(gè)封裝,仿照安卓的RelativeLayout布局設(shè)置,子組件也可以作為錨點(diǎn)進(jìn)行布局,需要給錨點(diǎn)組件設(shè)置唯一id。
看一下展示效果和源碼:
布局代碼:
import { AlignRules } from '../utils/AlignRules'
@Entry
@ComponentV2
struct StackTest{
build() {
Column(){
Stack({alignContent:Alignment.TopStart}){
Row(){}.width(120).height(120).backgroundColor(Color.Yellow)
Row(){}.width(90).height(90).backgroundColor(Color.Brown)
Row(){}.width(60).height(60).backgroundColor(Color.Red)
Row(){}.width(30).height(30).backgroundColor(Color.Black)
}.width('100%').height('30%').backgroundColor(Color.Gray)
Stack({ alignContent: Alignment.BottomEnd }){
Row(){}.width(120).height(120).backgroundColor(Color.Yellow)
Row(){}.width(90).height(90).backgroundColor(Color.Brown)
Row(){}.width(60).height(60).backgroundColor(Color.Red)
Row(){}.width(30).height(30).backgroundColor(Color.White)
}.width('100%').height('30%').backgroundColor(Color.Green)
RelativeContainer() {
Row(){}.width(120).height(120).backgroundColor(Color.Yellow)
Row(){}.width(140).height(140).backgroundColor(Color.Orange).alignRules(AlignRules.alignParentTopCenter)
Row(){}.width(30).height(30).backgroundColor(Color.Black).alignRules(AlignRules.alignParentRightTop)
Row(){}.width(60).height(60).backgroundColor(Color.Red).alignRules(AlignRules.centerInParent).id("red")
Row(){}.width(80).height(80).backgroundColor(Color.Brown).alignRules(AlignRules.alignParentLeftBottom)
Row(){}.width(100).height(100).backgroundColor(Color.Yellow).alignRules(AlignRules.alignParentRightBottom)
Row(){}.width(70).height(70).backgroundColor(0xd2cab3).alignRules(AlignRules.alignParentRightBottom)
Row(){}.width(30).height(30).backgroundColor('#e1dede').alignRules(AlignRules.alignParentRightBottom)
Row(){}.width(60).height(60).backgroundColor(Color.Pink).alignRules(AlignRules.below('red'))
}.width('100%').height('30%').backgroundColor(Color.Blue)
}
}
}
AlignRules封裝:
export class AlignRules{
//居中
static centerInParent:AlignRuleOption = {
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
}
//頂部居中
static alignParentTopCenter:AlignRuleOption = {
top: { anchor: '__container__', align: VerticalAlign.Top },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
}
//底部居中
static alignParentBottomCenter:AlignRuleOption = {
bottom: { anchor: '__container__', align: VerticalAlign.Bottom },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
}
//右上
static alignParentRightTop:AlignRuleOption = {
top: { anchor: '__container__', align: VerticalAlign.Top },
right: { anchor: '__container__', align: HorizontalAlign.End }
}
//靠右居中
static alignParentRightCenter:AlignRuleOption = {
center: { anchor: '__container__', align: VerticalAlign.Center },
right: { anchor: '__container__', align: HorizontalAlign.End }
}
//右下
static alignParentRightBottom:AlignRuleOption = {
bottom: { anchor: '__container__', align: VerticalAlign.Bottom },
right: { anchor: '__container__', align: HorizontalAlign.End }
}
//左上 默認(rèn)位置 不需要設(shè)置
//靠左居中
static alignParentLeftCenter:AlignRuleOption = {
center: { anchor: '__container__', align: VerticalAlign.Center },
left: { anchor: '__container__', align: HorizontalAlign.Start }
}
//左下
static alignParentLeftBottom:AlignRuleOption = {
bottom: { anchor: '__container__', align: VerticalAlign.Bottom },
left: { anchor: '__container__', align: HorizontalAlign.Start }
}
//在錨點(diǎn)的下方
static below(id:string):AlignRuleOption {
return {
top:{ anchor: id, align: VerticalAlign.Bottom },
middle: { anchor: id, align: HorizontalAlign.Center }
}
}
}