鴻蒙學習實戰之路-彈性佈局 Flex 全攻略
最近好多朋友問我:"我想在鴻蒙裏做個漂亮的頁面佈局,但 Row 和 Column 太死板了,有沒有更靈活的方式?"_
今天這篇,我就手把手帶你搞定彈性佈局(Flex)——鴻蒙裏最靈活的佈局神器!全程都是能跑的代碼和避坑指南,看完你就能輕鬆實現各種複雜佈局~ o(∩_∩)o
一、什麼是彈性佈局?
彈性佈局(Flex)就像一個會伸縮的容器,能自動幫你調整裏面元素的位置和大小。想象一下,你有一個彈性口袋,不管裏面裝多少東西,它都能自動分配空間,讓東西擺得整整齊齊~
核心概念:
- 主軸:元素排列的方向(水平/垂直)
- 交叉軸:垂直於主軸的方向
這兩個軸是理解 Flex 的關鍵,咱們先記住它們~
二、快速上手:寫一個簡單的 Flex 佈局
咱們先寫一個最基礎的彈性佈局,感受一下它的威力!
@Entry
@Component
struct FlexBasicExample {
build() {
Column() {
// 創建一個水平方向的Flex容器
Flex() {
Text('我是第一個元素').width('33%').height(50).backgroundColor('#F5DEB3')
Text('我是第二個元素').width('33%').height(50).backgroundColor('#D2B48C')
Text('我是第三個元素').width('33%').height(50).backgroundColor('#F5DEB3')
}
.height(70)
.width('90%')
.padding(10)
.backgroundColor('#AFEEEE')
}
.width('100%')
.height('100%')
}
}
效果:三個元素會自動在水平方向上排列,每個佔容器寬度的 33%~
🥦 西蘭花小貼士: Flex 默認是水平方向(Row)排列的,這也是最常用的佈局方式~
三、佈局方向:靈活控制元素排列
剛才咱們用的是默認的水平方向,其實 Flex 支持四種佈局方向:
1. 水平方向(默認)
Flex({ direction: FlexDirection.Row }) {
// 元素內容
}
2. 水平反向
Flex({ direction: FlexDirection.RowReverse }) {
Text('1').width('33%').height(50).backgroundColor('#F5DEB3')
Text('2').width('33%').height(50).backgroundColor('#D2B48C')
Text('3').width('33%').height(50).backgroundColor('#F5DEB3')
}
效果:元素從右往左排列~
3. 垂直方向
Flex({ direction: FlexDirection.Column }) {
// 元素內容
}
4. 垂直反向
Flex({ direction: FlexDirection.ColumnReverse }) {
// 元素內容
}
🥦 西蘭花警告: 方向設置會影響主軸和交叉軸的方向哦!比如垂直方向時,主軸變成了垂直方向,交叉軸變成了水平方向~
四、佈局換行:處理元素太多的情況
如果元素總寬度超過了容器寬度,Flex 默認會壓縮元素。但咱們可以設置換行,讓元素自動換行排列~
1. 不換行(默認)
Flex({ wrap: FlexWrap.NoWrap }) {
Text('1').width('50%').height(50).backgroundColor('#F5DEB3')
Text('2').width('50%').height(50).backgroundColor('#D2B48C')
Text('3').width('50%').height(50).backgroundColor('#F5DEB3')
}
效果:三個元素都被壓縮在一行裏~
2. 換行
Flex({ wrap: FlexWrap.Wrap }) {
Text('1').width('50%').height(50).backgroundColor('#F5DEB3')
Text('2').width('50%').height(50).backgroundColor('#D2B48C')
Text('3').width('50%').height(50).backgroundColor('#D2B48C')
}
效果:第三個元素自動換到了下一行~
3. 反向換行
Flex({ wrap: FlexWrap.WrapReverse }) {
// 元素內容
}
五、主軸對齊:控制元素在主軸上的位置
主軸對齊是 Flex 最常用的功能之一,它能控制元素在主軸方向上的排列方式。咱們來看看常用的幾種:
1. 起始對齊(默認)
Flex({ justifyContent: FlexAlign.Start }) {
Text('1').width('20%').height(50).backgroundColor('#F5DEB3')
Text('2').width('20%').height(50).backgroundColor('#D2B48C')
Text('3').width('20%').height(50).backgroundColor('#F5DEB3')
}
效果:元素從主軸起始端排列~
2. 居中對齊
Flex({ justifyContent: FlexAlign.Center }) {
// 元素內容
}
效果:元素在主軸方向居中~
3. 末尾對齊
Flex({ justifyContent: FlexAlign.End }) {
// 元素內容
}
4. 均勻分佈
Flex({ justifyContent: FlexAlign.SpaceBetween }) {
// 元素內容
}
效果:元素之間距離相等,兩端貼邊~
5. 環繞分佈
Flex({ justifyContent: FlexAlign.SpaceAround }) {
// 元素內容
}
效果:元素之間距離相等,兩端距離是中間的一半~
6. 等間距分佈
Flex({ justifyContent: FlexAlign.SpaceEvenly }) {
// 元素內容
}
效果:所有間距都相等~
六、交叉軸對齊:控制元素在交叉軸上的位置
交叉軸對齊控制元素在垂直於主軸方向上的排列。Flex 容器和子元素都可以設置交叉軸對齊~
1. 容器設置交叉軸對齊
Flex({ alignItems: ItemAlign.Center }) {
Text('1').width('33%').height(30).backgroundColor('#F5DEB3')
Text('2').width('33%').height(40).backgroundColor('#D2B48C')
Text('3').width('33%').height(50).backgroundColor('#F5DEB3')
}
.size({ width: '90%', height: 80 })
效果:不同高度的元素在交叉軸上居中對齊~
常用的交叉軸對齊方式:
ItemAlign.Start:交叉軸起始端對齊ItemAlign.Center:交叉軸居中對齊ItemAlign.End:交叉軸末尾對齊ItemAlign.Stretch:拉伸填充交叉軸ItemAlign.Baseline:文本基線對齊
2. 子元素單獨設置交叉軸對齊
咱們還可以給某個子元素單獨設置交叉軸對齊,覆蓋容器的設置~
Flex() {
Text('1').width('33%').height(30).backgroundColor('#F5DEB3')
.alignSelf(ItemAlign.End) // 單獨設置這個元素在交叉軸末尾對齊
Text('2').width('33%').height(40).backgroundColor('#D2B48C')
Text('3').width('33%').height(50).backgroundColor('#F5DEB3')
}
🥦 西蘭花小貼士: alignSelf 是子元素的屬性,可以單獨控制某個元素的交叉軸對齊方式~
七、實戰案例:實現一個導航欄
咱們來做個實戰案例——實現一個手機應用常見的導航欄佈局~
@Entry
@Component
struct FlexNavBarExample {
build() {
Column() {
// 導航欄容器
Flex() {
// 左側返回按鈕
Text('←').fontSize(24)
.width(40).height(40)
.textAlign(TextAlign.Center)
.alignSelf(ItemAlign.Center)
// 標題(自動佔滿剩餘空間)
Text('彈性佈局教程')
.fontSize(18)
.fontWeight(FontWeight.Bold)
.flexGrow(1) // 自動佔滿剩餘空間
.textAlign(TextAlign.Center)
// 右側更多按鈕
Text('⋮').fontSize(24)
.width(40).height(40)
.textAlign(TextAlign.Center)
.alignSelf(ItemAlign.Center)
}
.width('100%')
.height(56)
.padding({ left: 16, right: 16 })
.backgroundColor('#FFFFFF')
.borderBottom({ width: 1, color: '#E5E5E5' })
}
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5')
}
}
解析:
- 使用
flexGrow(1)讓標題自動佔滿剩餘空間 - 使用
alignSelf讓按鈕垂直居中 - 整體實現了一個常見的導航欄佈局~
🥦 西蘭花警告: flexGrow 屬性非常好用,它能讓元素自動分配剩餘空間。但要注意,只有在主軸有剩餘空間時才會生效哦!
八、高級技巧:Flex 的更多用法
1. 自適應拉伸
使用 flexGrow 可以讓元素自動分配剩餘空間,實現自適應佈局~
Flex() {
Text('固定寬度').width(100).height(50).backgroundColor('#F5DEB3')
Text('自適應寬度').height(50).backgroundColor('#D2B48C')
.flexGrow(1) // 佔滿剩餘空間
Text('固定寬度').width(100).height(50).backgroundColor('#F5DEB3')
}
2. 嵌套 Flex
咱們可以在 Flex 容器裏再放 Flex 容器,實現更復雜的佈局~
Flex({ direction: FlexDirection.Column }) {
// 頂部欄
Flex() {
// 頂部欄內容
}
// 中間內容區
Flex() {
// 中間內容
}
.flexGrow(1) // 佔滿剩餘空間
// 底部欄
Flex() {
// 底部欄內容
}
}
九、避坑指南
1. 方向設置影響軸的方向
- 水平方向:主軸是水平,交叉軸是垂直
- 垂直方向:主軸是垂直,交叉軸是水平
2. 對齊方式的優先級
- 子元素的
alignSelf優先級高於容器的alignItems - 主軸對齊和交叉軸對齊是獨立的,需要分別設置
3. 換行和不換行的區別
NoWrap:元素會被壓縮Wrap:元素會自動換行
4. flexGrow 的使用場景
- 只有在主軸有剩餘空間時才會生效
- 可以同時給多個元素設置,按比例分配空間
十、額外案例:實現一個商品卡片
咱們來實現一個電商應用中常見的商品卡片佈局,只使用色塊和 Flex 佈局~
@Entry
@Component
struct FlexProductCardExample {
build() {
Column() {
Text('商品卡片示例')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.margin(20)
// 商品卡片容器
Flex({ direction: FlexDirection.Column }) {
// 商品圖片區域(色塊模擬)
Stack() {
Text('商品圖片')
.fontSize(16)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
}
.width('100%')
.height(200)
.backgroundColor('#D2B48C')
// 商品信息區域
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start }) {
// 商品標題
Text('這是一個非常好用的商品')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.margin(8)
// 商品描述
Text('這個商品真的很不錯,買了不會後悔的~')
.fontSize(14)
.fontColor('#666666')
.margin(12)
// 價格和購買按鈕區域
Flex() {
// 價格
Text('¥99.99')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor('#FF4444')
.flexGrow(1)
// 購買按鈕
Text('立即購買')
.width(100)
.height(36)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
.backgroundColor('#FF4444')
.borderRadius(18)
}
}
}
.width('90%')
.backgroundColor(Color.White)
.borderRadius(12)
.shadow({
radius: 4,
color: '#00000020',
offsetX: 0,
offsetY: 2
})
}
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5')
}
}
代碼解析:
- 整體使用垂直方向的 Flex 容器作為卡片主體
- 頂部用 Stack 和色塊模擬商品圖片區域
- 中間使用垂直 Flex 容器存放商品信息
- 底部使用水平 Flex 容器實現價格和購買按鈕的佈局,價格區域用
flexGrow(1)自動佔滿剩餘空間 - 最後添加圓角和陰影效果,讓卡片更立體
這個案例展示瞭如何用 Flex 佈局實現一個常見的商品卡片,代碼簡單易懂,只使用了色塊和文本,沒有依賴圖片~
🥦 西蘭花小貼士: 商品卡片是電商應用的核心組件,掌握這個佈局可以舉一反三,實現更多類似的卡片式設計~
寫在最後
恭喜你!現在你已經掌握了彈性佈局(Flex)的核心用法~ 這是鴻蒙開發中最靈活的佈局方式,幾乎能滿足所有的佈局需求~
下一步學習建議:
- 嘗試用 Flex 實現一個完整的頁面佈局
- 結合其他組件(如 Scroll、Swiper)使用 Flex
- 探索 Flex 的更多高級屬性
📚 推薦資料:
- 鴻蒙官方 Flex 文檔
我是鹽焗西蘭花, 不教理論,只給你能跑的代碼和避坑指南。 下期見!🥦