彈性布局(Flex)提供更加有效的方式對(duì)容器中的子元素進(jìn)行排列、對(duì)齊和分配剩余空間。容器默認(rèn)存在主軸與交叉軸,子元素默認(rèn)沿主軸排列,子元素在主軸方向的尺寸稱為主軸尺寸,在交叉軸方向的尺寸稱為交叉軸尺寸。彈性布局在開發(fā)場(chǎng)景中用例特別多,比如頁(yè)面頭部導(dǎo)航欄的均勻分布、頁(yè)面框架的搭建、多行數(shù)據(jù)的排列等等。
在彈性布局中,容器的子元素可以按照任意方向排列。通過設(shè)置參數(shù)direction,可以決定主軸的方向,從而控制子組件的排列方向。
FlexDirection.Row(默認(rèn)值):主軸為水平方向,子組件從起始端沿著水平方向開始排布。
- Flex({ direction: FlexDirection.Row }) {
- Text('1').width('33%').height(50).backgroundColor(0xF5DEB3)
- Text('2').width('33%').height(50).backgroundColor(0xD2B48C)
- Text('3').width('33%').height(50).backgroundColor(0xF5DEB3)
- }
- .height(70)
- .width('90%')
- .padding(10)
- .backgroundColor(0xAFEEEE)
FlexDirection.RowReverse:主軸為水平方向,子組件從終點(diǎn)端沿著FlexDirection. Row相反的方向開始排布。
- Flex({ direction: FlexDirection.RowReverse }) {
- Text('1').width('33%').height(50).backgroundColor(0xF5DEB3)
- Text('2').width('33%').height(50).backgroundColor(0xD2B48C)
- Text('3').width('33%').height(50).backgroundColor(0xF5DEB3)
- }
- .height(70)
- .width('90%')
- .padding(10)
- .backgroundColor(0xAFEEEE)
FlexDirection.Column:主軸為垂直方向,子組件從起始端沿著垂直方向開始排布。
- Flex({ direction: FlexDirection.Column }) {
- Text('1').width('100%').height(50).backgroundColor(0xF5DEB3)
- Text('2').width('100%').height(50).backgroundColor(0xD2B48C)
- Text('3').width('100%').height(50).backgroundColor(0xF5DEB3)
- }
- .height(70)
- .width('90%')
- .padding(10)
- .backgroundColor(0xAFEEEE)
FlexDirection.ColumnReverse:主軸為垂直方向,子組件從終點(diǎn)端沿著FlexDirection. Column相反的方向開始排布。
- Flex({ direction: FlexDirection.ColumnReverse }) {
- Text('1').width('100%').height(50).backgroundColor(0xF5DEB3)
- Text('2').width('100%').height(50).backgroundColor(0xD2B48C)
- Text('3').width('100%').height(50).backgroundColor(0xF5DEB3)
- }
- .height(70)
- .width('90%')
- .padding(10)
- .backgroundColor(0xAFEEEE)
彈性布局分為單行布局和多行布局。默認(rèn)情況下,F(xiàn)lex容器中的子元素都排在一條線(又稱“軸線”)上。wrap屬性控制當(dāng)子元素主軸尺寸之和大于容器主軸尺寸時(shí),F(xiàn)lex是單行布局還是多行布局。在多行布局時(shí),通過交叉軸方向,確認(rèn)新行堆疊方向。
FlexWrap. NoWrap(默認(rèn)值):不換行。如果子組件的寬度總和大于父元素的寬度,則子組件會(huì)被壓縮寬度。
- Flex({ wrap: FlexWrap.NoWrap }) {
- Text('1').width('50%').height(50).backgroundColor(0xF5DEB3)
- Text('2').width('50%').height(50).backgroundColor(0xD2B48C)
- Text('3').width('50%').height(50).backgroundColor(0xF5DEB3)
- }
- .width('90%')
- .padding(10)
- .backgroundColor(0xAFEEEE)
FlexWrap. Wrap:換行,每一行子組件按照主軸方向排列。
- Flex({ wrap: FlexWrap.Wrap }) {
- Text('1').width('50%').height(50).backgroundColor(0xF5DEB3)
- Text('2').width('50%').height(50).backgroundColor(0xD2B48C)
- Text('3').width('50%').height(50).backgroundColor(0xD2B48C)
- }
- .width('90%')
- .padding(10)
- .backgroundColor(0xAFEEEE)
FlexWrap. WrapReverse:換行,每一行子組件按照主軸反方向排列。
- Flex({ wrap: FlexWrap.WrapReverse}) {
- Text('1').width('50%').height(50).backgroundColor(0xF5DEB3)
- Text('2').width('50%').height(50).backgroundColor(0xD2B48C)
- Text('3').width('50%').height(50).backgroundColor(0xF5DEB3)
- }
- .width('90%')
- .padding(10)
- .backgroundColor(0xAFEEEE)
FlexAlign.Start(默認(rèn)值):子組件在主軸方向起始端對(duì)齊, 第一個(gè)子組件與父元素邊沿對(duì)齊,其他元素與前一個(gè)元素對(duì)齊。
- Flex({ justifyContent: FlexAlign.Start }) {
- Text('1').width('20%').height(50).backgroundColor(0xF5DEB3)
- Text('2').width('20%').height(50).backgroundColor(0xD2B48C)
- Text('3').width('20%').height(50).backgroundColor(0xF5DEB3)
- }
- .width('90%')
- .padding({ top: 10, bottom: 10 })
- .backgroundColor(0xAFEEEE)
FlexAlign.Center:子組件在主軸方向居中對(duì)齊。
- Flex({ justifyContent: FlexAlign.Center }) {
- Text('1').width('20%').height(50).backgroundColor(0xF5DEB3)
- Text('2').width('20%').height(50).backgroundColor(0xD2B48C)
- Text('3').width('20%').height(50).backgroundColor(0xF5DEB3)
- }
- .width('90%')
- .padding({ top: 10, bottom: 10 })
- .backgroundColor(0xAFEEEE)
FlexAlign.End:子組件在主軸方向終點(diǎn)端對(duì)齊, 最后一個(gè)子組件與父元素邊沿對(duì)齊,其他元素與后一個(gè)元素對(duì)齊。
- Flex({ justifyContent: FlexAlign.End }) {
- Text('1').width('20%').height(50).backgroundColor(0xF5DEB3)
- Text('2').width('20%').height(50).backgroundColor(0xD2B48C)
- Text('3').width('20%').height(50).backgroundColor(0xF5DEB3)
- }
- .width('90%')
- .padding({ top: 10, bottom: 10 })
- .backgroundColor(0xAFEEEE)
FlexAlign.SpaceBetween:Flex主軸方向均勻分配彈性元素,相鄰子組件之間距離相同。第一個(gè)子組件和最后一個(gè)子組件與父元素邊沿對(duì)齊。
- Flex({ justifyContent: FlexAlign.SpaceBetween }) {
- Text('1').width('20%').height(50).backgroundColor(0xF5DEB3)
- Text('2').width('20%').height(50).backgroundColor(0xD2B48C)
- Text('3').width('20%').height(50).backgroundColor(0xF5DEB3)
- }
- .width('90%')
- .padding({ top: 10, bottom: 10 })
- .backgroundColor(0xAFEEEE)
FlexAlign.SpaceAround:Flex主軸方向均勻分配彈性元素,相鄰子組件之間距離相同。第一個(gè)子組件到主軸起始端的距離和最后一個(gè)子組件到主軸終點(diǎn)端的距離是相鄰元素之間距離的一半。
- Flex({ justifyContent: FlexAlign.SpaceAround }) {
- Text('1').width('20%').height(50).backgroundColor(0xF5DEB3)
- Text('2').width('20%').height(50).backgroundColor(0xD2B48C)
- Text('3').width('20%').height(50).backgroundColor(0xF5DEB3)
- }
- .width('90%')
- .padding({ top: 10, bottom: 10 })
- .backgroundColor(0xAFEEEE)
FlexAlign.SpaceEvenly:Flex主軸方向元素等間距布局,相鄰子組件之間的間距、第一個(gè)子組件與主軸起始端的間距、最后一個(gè)子組件到主軸終點(diǎn)端的間距均相等。
- Flex({ justifyContent: FlexAlign.SpaceEvenly }) {
- Text('1').width('20%').height(50).backgroundColor(0xF5DEB3)
- Text('2').width('20%').height(50).backgroundColor(0xD2B48C)
- Text('3').width('20%').height(50).backgroundColor(0xF5DEB3)
- }
- .width('90%')
- .padding({ top: 10, bottom: 10 })
- .backgroundColor(0xAFEEEE)
ItemAlign.Auto:使用Flex容器中默認(rèn)配置。
- Flex({ alignItems: ItemAlign.Auto }) {
- Text('1').width('33%').height(30).backgroundColor(0xF5DEB3)
- Text('2').width('33%').height(40).backgroundColor(0xD2B48C)
- Text('3').width('33%').height(50).backgroundColor(0xF5DEB3)
- }
- .size({ width: '90%', height: 80 })
- .padding(10)
- .backgroundColor(0xAFEEEE)
ItemAlign.Start:交叉軸方向首部對(duì)齊。
- Flex({ alignItems: ItemAlign.Start }) {
- Text('1').width('33%').height(30).backgroundColor(0xF5DEB3)
- Text('2').width('33%').height(40).backgroundColor(0xD2B48C)
- Text('3').width('33%').height(50).backgroundColor(0xF5DEB3)
- }
- .size({ width: '90%', height: 80 })
- .padding(10)
- .backgroundColor(0xAFEEEE)
ItemAlign.Center:交叉軸方向居中對(duì)齊。
- Flex({ alignItems: ItemAlign.Center }) {
- Text('1').width('33%').height(30).backgroundColor(0xF5DEB3)
- Text('2').width('33%').height(40).backgroundColor(0xD2B48C)
- Text('3').width('33%').height(50).backgroundColor(0xF5DEB3)
- }
- .size({ width: '90%', height: 80 })
- .padding(10)
- .backgroundColor(0xAFEEEE)
ItemAlign.End:交叉軸方向底部對(duì)齊。
- Flex({ alignItems: ItemAlign.End }) {
- Text('1').width('33%').height(30).backgroundColor(0xF5DEB3)
- Text('2').width('33%').height(40).backgroundColor(0xD2B48C)
- Text('3').width('33%').height(50).backgroundColor(0xF5DEB3)
- }
- .size({ width: '90%', height: 80 })
- .padding(10)
- .backgroundColor(0xAFEEEE)
ItemAlign.Stretch:交叉軸方向拉伸填充,在未設(shè)置尺寸時(shí),拉伸到容器尺寸。
- Flex({ alignItems: ItemAlign.Stretch }) {
- Text('1').width('33%').backgroundColor(0xF5DEB3)
- Text('2').width('33%').backgroundColor(0xD2B48C)
- Text('3').width('33%').backgroundColor(0xF5DEB3)
- }
- .size({ width: '90%', height: 80 })
- .padding(10)
- .backgroundColor(0xAFEEEE)
ItemAlign. Baseline:交叉軸方向文本基線對(duì)齊。
- Flex({ alignItems: ItemAlign.Baseline }) {
- Text('1').width('33%').height(30).backgroundColor(0xF5DEB3)
- Text('2').width('33%').height(40).backgroundColor(0xD2B48C)
- Text('3').width('33%').height(50).backgroundColor(0xF5DEB3)
- }
- .size({ width: '90%', height: 80 })
- .padding(10)
- .backgroundColor(0xAFEEEE)
子組件的alignSelf屬性也可以設(shè)置子組件在父容器交叉軸的對(duì)齊格式,且會(huì)覆蓋Flex布局容器中alignItems配置。如下例所示:
- Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) { // 容器組件設(shè)置子組件居中
- Text('alignSelf Start').width('25%').height(80)
- .alignSelf(ItemAlign.Start)
- .backgroundColor(0xF5DEB3)
- Text('alignSelf Baseline')
- .alignSelf(ItemAlign.Baseline)
- .width('25%')
- .height(80)
- .backgroundColor(0xD2B48C)
- Text('alignSelf Baseline').width('25%').height(100)
- .backgroundColor(0xF5DEB3)
- .alignSelf(ItemAlign.Baseline)
- Text('no alignSelf').width('25%').height(100)
- .backgroundColor(0xD2B48C)
- Text('no alignSelf').width('25%').height(100)
- .backgroundColor(0xF5DEB3)
- }.width('90%').height(220).backgroundColor(0xAFEEEE)
上例中,F(xiàn)lex容器中alignItems設(shè)置交叉軸子組件的對(duì)齊方式為居中,子組件自身設(shè)置了alignSelf屬性的情況,覆蓋父組件的alignItems值,表現(xiàn)為alignSelf的定義。
可以通過alignContent參數(shù)設(shè)置子組件各行在交叉軸剩余空間內(nèi)的對(duì)齊方式,只在多行的flex布局中生效,可選值有:
FlexAlign.Start:子組件各行與交叉軸起點(diǎn)對(duì)齊。
- Flex({ justifyContent: FlexAlign.SpaceBetween, wrap: FlexWrap.Wrap, alignContent: FlexAlign.Start }) {
- Text('1').width('30%').height(20).backgroundColor(0xF5DEB3)
- Text('2').width('60%').height(20).backgroundColor(0xD2B48C)
- Text('3').width('40%').height(20).backgroundColor(0xD2B48C)
- Text('4').width('30%').height(20).backgroundColor(0xF5DEB3)
- Text('5').width('20%').height(20).backgroundColor(0xD2B48C)
- }
- .width('90%')
- .height(100)
- .backgroundColor(0xAFEEEE)
FlexAlign.Center:子組件各行在交叉軸方向居中對(duì)齊。
- Flex({ justifyContent: FlexAlign.SpaceBetween, wrap: FlexWrap.Wrap, alignContent: FlexAlign.Center }) {
- Text('1').width('30%').height(20).backgroundColor(0xF5DEB3)
- Text('2').width('60%').height(20).backgroundColor(0xD2B48C)
- Text('3').width('40%').height(20).backgroundColor(0xD2B48C)
- Text('4').width('30%').height(20).backgroundColor(0xF5DEB3)
- Text('5').width('20%').height(20).backgroundColor(0xD2B48C)
- }
- .width('90%')
- .height(100)
- .backgroundColor(0xAFEEEE)
FlexAlign.End:子組件各行與交叉軸終點(diǎn)對(duì)齊。
- Flex({ justifyContent: FlexAlign.SpaceBetween, wrap: FlexWrap.Wrap, alignContent: FlexAlign.End }) {
- Text('1').width('30%').height(20).backgroundColor(0xF5DEB3)
- Text('2').width('60%').height(20).backgroundColor(0xD2B48C)
- Text('3').width('40%').height(20).backgroundColor(0xD2B48C)
- Text('4').width('30%').height(20).backgroundColor(0xF5DEB3)
- Text('5').width('20%').height(20).backgroundColor(0xD2B48C)
- }
- .width('90%')
- .height(100)
- .backgroundColor(0xAFEEEE)
FlexAlign.SpaceBetween:子組件各行與交叉軸兩端對(duì)齊,各行間垂直間距平均分布。
- Flex({ justifyContent: FlexAlign.SpaceBetween, wrap: FlexWrap.Wrap, alignContent: FlexAlign.SpaceBetween }) {
- Text('1').width('30%').height(20).backgroundColor(0xF5DEB3)
- Text('2').width('60%').height(20).backgroundColor(0xD2B48C)
- Text('3').width('40%').height(20).backgroundColor(0xD2B48C)
- Text('4').width('30%').height(20).backgroundColor(0xF5DEB3)
- Text('5').width('20%').height(20).backgroundColor(0xD2B48C)
- }
- .width('90%')
- .height(100)
- .backgroundColor(0xAFEEEE)
FlexAlign.SpaceAround:子組件各行間距相等,是元素首尾行與交叉軸兩端距離的兩倍。
- Flex({ justifyContent: FlexAlign.SpaceBetween, wrap: FlexWrap.Wrap, alignContent: FlexAlign.SpaceAround }) {
- Text('1').width('30%').height(20).backgroundColor(0xF5DEB3)
- Text('2').width('60%').height(20).backgroundColor(0xD2B48C)
- Text('3').width('40%').height(20).backgroundColor(0xD2B48C)
- Text('4').width('30%').height(20).backgroundColor(0xF5DEB3)
- Text('5').width('20%').height(20).backgroundColor(0xD2B48C)
- }
- .width('90%')
- .height(100)
- .backgroundColor(0xAFEEEE)
FlexAlign.SpaceEvenly: 子組件各行間距,子組件首尾行與交叉軸兩端距離都相等。
- Flex({ justifyContent: FlexAlign.SpaceBetween, wrap: FlexWrap.Wrap, alignContent: FlexAlign.SpaceEvenly }) {
- Text('1').width('30%').height(20).backgroundColor(0xF5DEB3)
- Text('2').width('60%').height(20).backgroundColor(0xD2B48C)
- Text('3').width('40%').height(20).backgroundColor(0xD2B48C)
- Text('4').width('30%').height(20).backgroundColor(0xF5DEB3)
- Text('5').width('20%').height(20).backgroundColor(0xD2B48C)
- }
- .width('90%')
- .height(100)
- .backgroundColor(0xAFEEEE)
在彈性布局父組件尺寸不夠大的時(shí)候,通過子組件的下面幾個(gè)屬性設(shè)置其在父容器的占比,達(dá)到自適應(yīng)布局能力。
flexBasis:設(shè)置子組件在父容器主軸方向上的基準(zhǔn)尺寸。如果設(shè)置了該值,則子項(xiàng)占用的空間為設(shè)置的值;如果沒設(shè)置該屬性,那子項(xiàng)的空間為width/height的值。
- Flex() {
- Text('flexBasis("auto")')
- .flexBasis('auto') // 未設(shè)置width以及flexBasis值為auto,內(nèi)容自身寬度
- .height(100)
- .backgroundColor(0xF5DEB3)
- Text('flexBasis("auto")' + ' width("40%")')
- .width('40%')
- .flexBasis('auto') //設(shè)置width以及flexBasis值auto,使用width的值
- .height(100)
- .backgroundColor(0xD2B48C)
- Text('flexBasis(100)') // 未設(shè)置width以及flexBasis值為100,寬度為100vp
- .fontSize(15)
- .flexBasis(100)
- .height(100)
- .backgroundColor(0xF5DEB3)
- Text('flexBasis(100)')
- .fontSize(15)
- .flexBasis(100)
- .width(200) // flexBasis值為100,覆蓋width的設(shè)置值,寬度為100vp
- .height(100)
- .backgroundColor(0xD2B48C)
- }.width('90%').height(120).padding(10).backgroundColor(0xAFEEEE)
- Flex() {
- Text('flexGrow(2)')
- .flexGrow(2)
- .width(100)
- .height(100)
- .backgroundColor(0xF5DEB3)
- Text('flexGrow(3)')
- .flexGrow(3)
- .width(100)
- .height(100)
- .backgroundColor(0xD2B48C)
- Text('no flexGrow')
- .width(100)
- .height(100)
- .backgroundColor(0xF5DEB3)
- }.width(420).height(120).padding(10).backgroundColor(0xAFEEEE)
父容器寬度420vp,三個(gè)子元素原始寬度為100vp,左右padding為20vp,總和320vp,剩余空間100vp根據(jù)flexGrow值的占比分配給子元素,未設(shè)置flexGrow的子元素不參與“瓜分”。
第一個(gè)元素以及第二個(gè)元素以2:3分配剩下的100vp。第一個(gè)元素為100vp+100vp*2/5=140vp,第二個(gè)元素為100vp+100vp*3/5=160vp。
flexShrink: 當(dāng)父容器空間不足時(shí),子組件的壓縮比例。
- Flex({ direction: FlexDirection.Row }) {
- Text('flexShrink(3)')
- .fontSize(15)
- .flexShrink(3)
- .width(200)
- .height(100)
- .backgroundColor(0xF5DEB3)
- Text('no flexShrink')
- .width(200)
- .height(100)
- .backgroundColor(0xD2B48C)
- Text('flexShrink(2)')
- .flexShrink(2)
- .width(200)
- .height(100)
- .backgroundColor(0xF5DEB3)
- }.width(400).height(120).padding(10).backgroundColor(0xAFEEEE)
使用彈性布局,可以實(shí)現(xiàn)子組件沿水平方向排列,兩端對(duì)齊,子組件間距平分,豎直方向上子組件居中的效果。
- @Entry
- @Component
- struct FlexExample {
- build() {
- Column() {
- Column({ space: 5 }) {
- Flex({ direction: FlexDirection.Row, wrap: FlexWrap.NoWrap, justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
- Text('1').width('30%').height(50).backgroundColor(0xF5DEB3)
- Text('2').width('30%').height(50).backgroundColor(0xD2B48C)
- Text('3').width('30%').height(50).backgroundColor(0xF5DEB3)
- }
- .height(70)
- .width('90%')
- .backgroundColor(0xAFEEEE)
- }.width('100%').margin({ top: 5 })
- }.width('100%')
- }
- }
更多建議: