來吧!Flutter(7)-Row/Column
橫的還是直的?
Flutter 有為數眾多的佈局 Widget,其中最常用到的莫過於 Column 以及 Row Widget。因為是佈局 Widget,所以本身是沒有畫面的,必須要將需要顯示的 Widget 放在其 children 中。
除了可以將基本的 Widget 放在 children 中,還可以依照需求將複雜的 Widget 也放在其中,例如可以將 Row 放在 Column 中。
另外,可以針對其 children 設定 align(對齊),也可以拉伸其 children widget。
舉例來說:下方的畫面,是由一個 Column 裡面包含著四個子 widget,其中第一個子 Widget 是 Row。
程式碼:
Overflowed
Column 與 Row 都是屬於不可以捲動的 Widget,在這兩個 Widget 中,能擺放的大小就是 Parent Widget 的大小,如上圖,最外層的 Column 最大高度是 Scaffold body 的高度,Column 裡面的 Row 最大寬度則是 Column 的寬度。如果 Children 裡面擺放的內容超過最大可擺放的大小,在 debug 模式底下則會顯示黃色警示線(XXX OVERFLOWED),如下圖。
那麼,該如何解決 Overflowed 的問題呢?因為 Column 與 Row 皆不可捲動,所以超出畫面所能繪製的部分,則將無法顯示,所以只要將 Column 與 Row 利用 ***SingleChildScrollView Widget***包起來,在此 Widget 底下的子 Widget 就會成為可以捲動的,如此就可以解決 Overflowed 的問題。
或是可以利用 ListView Widget 來解決。
程式碼:
對齊
Column 的寬度是子 widget 的最大寬度,高度則是父 widget 的最大高度。
反之,Row 的高度是子 Widget 的最大高度,寬度則是父 widget 的最大寬度。
在 Column 以及 Row 中,提供了對齊的屬性:mainAxisAligmnent, crossAxisAlignment。
我們可以利用這兩個屬性改變對齊的方式。
mainAxisAlignment
就字面上意思來看,是主軸的對齊。有什麼作用呢?
首先,mainAxisAlignment 有下列幾個值:start, center, end, spaceAround, spaceEvenly, spaceBetween,下面分別使用這些值來示範。
- start(預設值)
當沒有設定 mainAxisAlignment 時,預設是 start。由下方的示意圖可以看出,start 是從左上角開始繪製。
- center
mainAxisAlignment.center 是會將 child widget 置中。
- end
mainAxisAlignment.end 是將 child 放置在最底下。
另外三個值:spaceAround, spaceEvenly, spaceBetween則是跟子 Widget 的間隔有關係。
- spaceAround
將空間平均分配,其中第一個以及最後一個子 widget 都只有一半的空間。
- spaceEvenly
與 spaceAround 不同,所有的子 widget 都有相同大小的間隔。
- spaceBetween
將第一個 Widget 與最後一個 Widget 分別放在最前與最後,其他的部分平均分配。
crossAxisAlignment
crossAxisAlignment 與 mainAxisAlignment 是相對的,如果是 Column,則是控制橫向;反之,Row 是控制縱向。
因 column 的寬度是跟子 widget 的最大寬度相同,Row 的高度則是跟子 widget 的最大高度相同。 在上方的範例中,column 所有子 widget 都是相同寬度,所以 Column 的寬度與每一個圖片的寬度都與相同,所以 crossAsisAlignment 是沒有作用的。
如果需要使用 crossAxisAlignment 屬性,Column 或是 Row 內子 Widget 的大小就不能一樣。
如下範例,我將第一張圖片的大小限制移掉。
可以發現,第一張圖片的寬度填滿了整個畫面,其餘的圖片則是放在畫面的中間。
- center(預設值)
Column 與 Row 的預設值都是 center,如上圖所示。
- start
將所有子 widget 的開始端與父 widget 的開始端對齊。如範例,因父 widget 的寬度是整個畫面,故子 widget 的開始端對齊最左邊。
- end
與 start 相反,所有子 widget 往最末端對齊,在此範例為向右對齊。
- stretch
將子 widget 的寬度拉長至與父 widget 的寬度同寬。
在這邊,我將第二張圖不使用 Card 包起來,直接將 Image 放在 children 中,可以發現,stretch 對於第二張圖片沒有作用,其三四張圖片的寬度皆被拉長。
原因是 Image 為固定高度,所以大小不會因為父類別而變動,Card 是動態大小,會依照子類別的大小而變動尺寸。
小記
Column 與 Row 是在 Flutter 中最普遍的 Widget,利用 Column 與 Row 可以將子類別按照順序排列,並且可以設定對齊方式。
使用上需要注意如果子 Widget 的尺寸太大,超過了父 widget 的大小,那麼就會發生 overflowed 的情況。可以利用 SingleChildScorllView 或是 ListView 來解決,或是子 widget 設定小一點(笑)
那麼,Column 與 Row 的介紹就到這邊,如果有問題的歡迎跟我討論。
上面的範例都是以 Column 做示範,大家也可以使用 Row 來操作看看。
最後,範例中使用的圖片皆是使用https://mixkit.co/free-stock-art/ 提供的免費圖片。
謝謝收看