W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
在上一節(jié)中我們講過通過Stack
和Positioned
,我們可以指定一個或多個子元素相對于父元素各個邊的精確偏移,并且可以重疊。但如果我們只想簡單的調(diào)整一個子元素在父元素中的位置的話,使用Align
組件會更簡單一些。
Align
組件可以調(diào)整子組件的位置,并且可以根據(jù)子組件的寬高來確定自身的的寬高,定義如下:
Align({
Key key,
this.alignment = Alignment.center,
this.widthFactor,
this.heightFactor,
Widget child,
})
alignment
: 需要一個AlignmentGeometry
類型的值,表示子組件在父組件中的起始位置。AlignmentGeometry
是一個抽象類,它有兩個常用的子類:Alignment
和 FractionalOffset
,我們將在下面的示例中詳細介紹。widthFactor
和heightFactor
是用于確定Align
組件本身寬高的屬性;它們是兩個縮放因子,會分別乘以子元素的寬、高,最終的結(jié)果就是Align
組件的寬高。如果值為null
,則組件的寬高將會占用盡可能多的空間。我們先來看一個簡單的例子:
Container(
height: 120.0,
width: 120.0,
color: Colors.blue[50],
child: Align(
alignment: Alignment.topRight,
child: FlutterLogo(
size: 60,
),
),
)
運行效果如圖4-11所示:
FlutterLogo
是 Flutter SDK 提供的一個組件,內(nèi)容就是 Flutter 的商標。在上面的例子中,我們顯式指定了Container
的寬、高都為 120。如果我們不顯式指定寬高,而通過同時指定widthFactor
和heightFactor
為2也是可以達到同樣的效果:
Align(
widthFactor: 2,
heightFactor: 2,
alignment: Alignment.topRight,
child: FlutterLogo(
size: 60,
),
),
因為FlutterLogo
的寬高為60,則Align
的最終寬高都為2*60=120
。
另外,我們通過Alignment.topRight
將FlutterLogo
定位在Container
的右上角。那Alignment.topRight
是什么呢?通過源碼我們可以看到其定義如下:
//右上角
static const Alignment topRight = Alignment(1.0, -1.0);
可以看到它只是Alignment
的一個實例,下面我們介紹一下Alignment
。
Alignment
繼承自AlignmentGeometry
,表示矩形內(nèi)的一個點,他有兩個屬性x
、y
,分別表示在水平和垂直方向的偏移,Alignment
定義如下:
Alignment(this.x, this.y)
Alignment
Widget 會以矩形的中心點作為坐標原點,即Alignment(0.0, 0.0)
。x
、y
的值從-1到1分別代表矩形左邊到右邊的距離和頂部到底邊的距離,因此2個水平(或垂直)單位則等于矩形的寬(或高),如Alignment(-1.0, -1.0)
代表矩形的左側(cè)頂點,而Alignment(1.0, 1.0)
代表右側(cè)底部終點,而Alignment(1.0, -1.0)
則正是右側(cè)頂點,即Alignment.topRight
。為了使用方便,矩形的原點、四個頂點,以及四條邊的終點在Alignment
類中都已經(jīng)定義為了靜態(tài)常量。
Alignment
可以通過其坐標轉(zhuǎn)換公式將其坐標轉(zhuǎn)為子元素的具體偏移坐標:
(Alignment.x*childWidth/2+childWidth/2, Alignment.y*childHeight/2+childHeight/2)
其中childWidth
為子元素的寬度,childHeight
為子元素高度。
現(xiàn)在我們再看看上面的示例,我們將Alignment(1.0, -1.0)
帶入上面公式,可得FlutterLogo
的實際偏移坐標正是(60,0)。下面再看一個例子:
Align(
widthFactor: 2,
heightFactor: 2,
alignment: Alignment(2,0.0),
child: FlutterLogo(
size: 60,
),
)
我們可以先想象一下運行效果:將Alignment(2,0.0)
帶入上述坐標轉(zhuǎn)換公式,可以得到FlutterLogo
的實際偏移坐標為(90,30)。實際運行如圖4-12所示:
FractionalOffset
繼承自 Alignment
,它和 Alignment
唯一的區(qū)別就是坐標原點不同!FractionalOffset
的坐標原點為矩形的左側(cè)頂點,這和布局系統(tǒng)的一致,所以理解起來會比較容易。FractionalOffset
的坐標轉(zhuǎn)換公式為:
實際偏移 = (FractionalOffse.x * childWidth, FractionalOffse.y * childHeight)
下面看一個例子:
Container(
height: 120.0,
width: 120.0,
color: Colors.blue[50],
child: Align(
alignment: FractionalOffset(0.2, 0.6),
child: FlutterLogo(
size: 60,
),
),
)
實際運行效果如圖4-13所示下:
我們將FractionalOffset(0.2, 0.6)
帶入坐標轉(zhuǎn)換公式得FlutterLogo
實際偏移為(12,36),和實際運行效果吻合。
可以看到,Align
和Stack
/Positioned
都可以用于指定子元素相對于父元素的偏移,但它們還是有兩個主要區(qū)別:
Stack
/Positioned
定位的的參考系可以是父容器矩形的四個頂點;而Align
則需要先通過alignment
參數(shù)來確定坐標原點,不同的alignment
會對應(yīng)不同原點,最終的偏移是需要通過alignment
的轉(zhuǎn)換公式來計算出。Stack
可以有多個子元素,并且子元素可以堆疊,而Align
只能有一個子元素,不存在堆疊。
我們在前面章節(jié)的例子中已經(jīng)使用過Center
組件來居中子元素了,現(xiàn)在我們正式來介紹一下它。通過查找SDK源碼,我們看到Center
組件定義如下:
class Center extends Align {
const Center({ Key key, double widthFactor, double heightFactor, Widget child })
: super(key: key, widthFactor: widthFactor, heightFactor: heightFactor, child: child);
}
可以看到Center
繼承自Align
,它比Align
只少了一個alignment
參數(shù);由于Align
的構(gòu)造函數(shù)中alignment
值為Alignment.center
,所以,我們可以認為Center
組件其實是對齊方式確定(Alignment.center
)了的Align
。
上面我們講過當widthFactor
或heightFactor
為null
時組件的寬高將會占用盡可能多的空間,這一點需要特別注意,我們通過一個示例說明:
...//省略無關(guān)代碼
DecoratedBox(
decoration: BoxDecoration(color: Colors.red),
child: Center(
child: Text("xxx"),
),
),
DecoratedBox(
decoration: BoxDecoration(color: Colors.red),
child: Center(
widthFactor: 1,
heightFactor: 1,
child: Text("xxx"),
),
)
運行效果如圖4-14所示:
本節(jié)重點介紹了Align
組件及兩種偏移類Alignment
和FractionalOffset
,讀者需要理解這兩種偏移類的區(qū)別及各自的坐標轉(zhuǎn)化公式。另外,在此建議讀者在需要制定一些精確的偏移時應(yīng)優(yōu)先使用FractionalOffset
,因為它的坐標原點和布局系統(tǒng)相同,能更容易算出實際偏移。
在后面,我們又介紹了Align
組件和Stack
/Positioned
、Center
的關(guān)系,讀者可以對比理解。
還有,熟悉 Web 開發(fā)的同學(xué)可能會發(fā)現(xiàn)Align
組件的特性和 Web 開發(fā)中相對定位(position: relative
)非常像,是的!在大多數(shù)時候,我們可以直接使用Align
組件來實現(xiàn) Web 中相對定位的效果,讀者可以類比記憶。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: