一. 單子布局組件
單子布局組件的含義是其只有一個(gè)子組件,可以通過設(shè)置一些屬性設(shè)置該子組件所在的位置信息等。比較常用的單子布局組件有:Align、Center、Padding、Container。
1.1. Align組件
1.1.1. ?Align介紹
看到Align這個(gè)詞,我們就知道它有我們的對齊方式有關(guān)。
在其他端的開發(fā)中(iOS、Android、前端)Align通常只是一個(gè)屬性而已,但是Flutter中Align也是一個(gè)組件。
我們可以通過源碼來看一下Align有哪些屬性:

這里我們特別解釋一下widthFactor和heightFactor作用:
因?yàn)樽咏M件在父組件中的對齊方式必須有一個(gè)前提,就是父組件得知道自己的范圍(寬度和高度);
如果widthFactor和heightFactor不設(shè)置,那么默認(rèn)Align會(huì)盡可能的大(盡可能占據(jù)自己所在的父組件);
我們也可以對他們進(jìn)行設(shè)置,比如widthFactor設(shè)置為3,那么相對于Align的寬度是子組件跨度的3倍;
1.1.2. Align演練
我們簡單演練一下Align

1.2. Center組件
1.2.1. Center介紹
事實(shí)上Center組件繼承自Align,只是將alignment設(shè)置為Alignment.center。
源碼分析

1.2.2. Center演練
我們將上面的代碼Align換成Center

1.3. Padding組件
1.3.1. Padding介紹
Padding組件在其他端也是一個(gè)屬性而已,但是在Flutter中是一個(gè)Widget,但是Flutter中沒有Margin這樣一個(gè)Widget,這是因?yàn)橥膺吘嘁部梢酝ㄟ^Padding來完成。
Padding通常用于設(shè)置子Widget到父Widget的邊距(你可以稱之為是父組件的內(nèi)邊距或子Widget的外邊距)。
源碼分析

1.3.2. Padding演練

1.4. Container組件
Container組件類似于其他Android中的View,iOS中的UIView。
如果你需要一個(gè)視圖,有一個(gè)背景顏色、圖像、有固定的尺寸、需要一個(gè)邊框、圓角等效果,那么就可以使用Container組件。
1.4.1. Container介紹
Container在開發(fā)中被使用的頻率是非常高的,特別是我們經(jīng)常會(huì)將其作為容器組件。
下面我們來看一下Container有哪些屬性:

大多數(shù)屬性在介紹其它容器時(shí)都已經(jīng)介紹過了,不再贅述,但有兩點(diǎn)需要說明:
容器的大小可以通過width、height屬性來指定,也可以通過constraints來指定,如果同時(shí)存在時(shí),width、height優(yōu)先。實(shí)際上Container內(nèi)部會(huì)根據(jù)width、height來生成一個(gè)constraints;
color和decoration是互斥的,實(shí)際上,當(dāng)指定color時(shí),Container內(nèi)會(huì)自動(dòng)創(chuàng)建一個(gè)decoration;
1.4.2. Container演練

1.4.3. BoxDecoration
Container有一個(gè)非常重要的屬性?decoration:
他對應(yīng)的類型是Decoration類型,但是它是一個(gè)抽象類。
在開發(fā)中,我們經(jīng)常使用它的實(shí)現(xiàn)類BoxDecoration來進(jìn)行實(shí)例化。
BoxDecoration常見屬性:

部分效果演示:


1.4.4. 實(shí)現(xiàn)圓角圖像

二. 多子布局組件
在開發(fā)中,我們經(jīng)常需要將多個(gè)Widget放在一起進(jìn)行布局,比如水平方向、垂直方向排列,甚至有時(shí)候需要他們進(jìn)行層疊,比如圖片上面放一段文字等;
這個(gè)時(shí)候我們需要使用多子布局組件(Multi-child layout widgets)。
比較常用的多子布局組件是Row、Column、Stack。
2.0 Flex組件
事實(shí)上,我們即將學(xué)習(xí)的Row組件和Column組件都繼承自Flex組件。
Flex組件和Row、Column屬性主要的區(qū)別就是多一個(gè)direction。
當(dāng)direction的值為Axis.horizontal的時(shí)候,則是Row。
當(dāng)direction的值為Axis.vertical的時(shí)候,則是Column。
在學(xué)習(xí)Row和Column之前,我們先學(xué)習(xí)主軸和交叉軸的概念。
因?yàn)镽ow是一行排布,Column是一列排布,那么它們都存在兩個(gè)方向,并且兩個(gè)Widget排列的方向應(yīng)該是對立的。
它們之中都有主軸(MainAxis)和交叉軸(CrossAxis)的概念。
2.1. Row組件
2.1.1. Row介紹
Row組件用于將所有的子Widget排成一行,實(shí)際上這種布局應(yīng)該是借鑒于Web的Flex布局。
如果熟悉Flex布局,會(huì)發(fā)現(xiàn)非常簡單。
mainAxisSize:
表示Row在主軸(水平)方向占用的空間,默認(rèn)是MainAxisSize.max,表示盡可能多的占用水平方向的空間,此時(shí)無論子widgets實(shí)際占用多少水平空間,Row的寬度始終等于水平方向的最大寬度
而MainAxisSize.min表示盡可能少的占用水平空間,當(dāng)子widgets沒有占滿水平剩余空間,則Row的實(shí)際寬度等于所有子widgets占用的的水平空間;
mainAxisAlignment:表示子Widgets在Row所占用的水平空間內(nèi)對齊方式
如果mainAxisSize值為MainAxisSize.min,則此屬性無意義,因?yàn)樽觲idgets的寬度等于Row的寬度
只有當(dāng)mainAxisSize的值為MainAxisSize.max時(shí),此屬性才有意義
MainAxisAlignment.start表示沿textDirection的初始方向?qū)R,
如textDirection取值為TextDirection.ltr時(shí),則MainAxisAlignment.start表示左對齊,textDirection取值為TextDirection.rtl時(shí)表示從右對齊。
而MainAxisAlignment.end和MainAxisAlignment.start正好相反;
MainAxisAlignment.center表示居中對齊。
crossAxisAlignment:表示子Widgets在縱軸方向的對齊方式
Row的高度等于子Widgets中最高的子元素高度
它的取值和MainAxisAlignment一樣(包含start、end、?center三個(gè)值)
不同的是crossAxisAlignment的參考系是verticalDirection,即verticalDirection值為VerticalDirection.down時(shí)crossAxisAlignment.start指頂部對齊,verticalDirection值為VerticalDirection.up時(shí),crossAxisAlignment.start指底部對齊;而crossAxisAlignment.end和crossAxisAlignment.start正好相反;
2.1.2. Row演練

2.1.3. mainAxisSize
默認(rèn)情況下,Row會(huì)盡可能占據(jù)多的寬度,讓子Widget在其中進(jìn)行排布,這是因?yàn)閙ainAxisSize屬性默認(rèn)值是MainAxisSize.max。
2.1.4. TextBaseline
2.1.5. Expanded
如果我們希望紅色和黃色的Container Widget不要設(shè)置固定的寬度,而是占據(jù)剩余的部分,這個(gè)時(shí)候應(yīng)該如何處理呢?這個(gè)時(shí)候我們可以使用?Expanded?來包裹 Container Widget,并且將它的寬度不設(shè)置值;flex屬性,彈性系數(shù),Row會(huì)根據(jù)兩個(gè)Expanded的彈性系數(shù)來決定它們占據(jù)剩下空間的比例

2.2. Column組件
Column組件用于將所有的子Widget排成一列,學(xué)會(huì)了前面的Row后,Column只是和row的方向不同而已。
2.2.1. Column介紹
我們直接看它的源碼:我們發(fā)現(xiàn)和Row屬性是一致的,不再解釋

2.2.2. Column演練
我們直接將Row的代碼中Row改為Column,查看代碼運(yùn)行效果:

2.3.1. Stack介紹
我們還是通過源碼來看一下Stack有哪些屬性:

參數(shù)解析:
alignment:此參數(shù)決定如何去對齊沒有定位(沒有使用Positioned)或部分定位的子widget。所謂部分定位,在這里**特指沒有在某一個(gè)軸上定位:**left、right為橫軸,top、bottom為縱軸,只要包含某個(gè)軸上的一個(gè)定位屬性就算在該軸上有定位。
textDirection:和Row、Wrap的textDirection功能一樣,都用于決定alignment對齊的參考系即:textDirection的值為TextDirection.ltr,則alignment的start代表左,end代表右;textDirection的值為TextDirection.rtl,則alignment的start代表右,end代表左。
fit:此參數(shù)用于決定沒有定位的子widget如何去適應(yīng)Stack的大小。StackFit.loose表示使用子widget的大小,StackFit.expand表示擴(kuò)伸到Stack的大小。
overflow:此屬性決定如何顯示超出Stack顯示空間的子widget,值為Overflow.clip時(shí),超出部分會(huì)被剪裁(隱藏),值為Overflow.visible?時(shí)則不會(huì)。
2.3.2. Stack演練
Stack會(huì)經(jīng)常和Positioned一起來使用,Positioned可以決定組件在Stack中的位置,用于實(shí)現(xiàn)類似于Web中的絕對定位效果。
我們來看一個(gè)簡單的演練:

注意:Positioned組件只能在Stack中使用。