層疊布局和Web中的絕對(duì)定位曲初、Android中的Frame布局是相似的,子組件可以根據(jù)距父容器四個(gè)角的位置來(lái)確定自身的位置杯聚。絕對(duì)定位允許子組件堆疊起來(lái)(按照代碼中聲明的順序)臼婆。Flutter中使用Stack和Positioned這兩個(gè)組件來(lái)配合實(shí)現(xiàn)絕對(duì)定位。Stack允許子組件堆疊幌绍,而Positioned用于根據(jù)Stack的四個(gè)角來(lái)確定子組件的位置颁褂。
Stack
Stack({
this.alignment = AlignmentDirectional.topStart,
this.textDirection,
this.fit = StackFit.loose,
this.overflow = Overflow.clip,
List<Widget> children = const <Widget>[],
})
alignment:此參數(shù)決定如何去對(duì)齊沒(méi)有定位(沒(méi)有使用Positioned)或部分定位的子組件。所謂部分定位傀广,在這里特指沒(méi)有在某一個(gè)軸上定位:left颁独、right為橫軸,top伪冰、bottom為縱軸誓酒,只要包含某個(gè)軸上的一個(gè)定位屬性就算在該軸上有定位。
textDirection:和Row贮聂、Wrap的textDirection功能一樣靠柑,都用于確定alignment對(duì)齊的參考系,即:textDirection的值為TextDirection.ltr吓懈,則alignment的start代表左歼冰,end代表右,即從左往右的順序骄瓣;textDirection的值為TextDirection.rtl停巷,則alignment的start代表右,end代表左榕栏,即從右往左的順序畔勤。
fit:此參數(shù)用于確定沒(méi)有定位的子組件如何去適應(yīng)Stack的大小。StackFit.loose表示使用子組件的大小扒磁,StackFit.expand表示擴(kuò)伸到Stack的大小庆揪。
overflow:此屬性決定如何顯示超出Stack顯示空間的子組件;值為Overflow.clip時(shí)妨托,超出部分會(huì)被剪裁(隱藏)缸榛,值為Overflow.visible 時(shí)則不會(huì)。
Positioned
const Positioned({
Key key,
this.left,
this.top,
this.right,
this.bottom,
this.width,
this.height,
@required Widget child,
})
left兰伤、top 内颗、right、 bottom分別代表離Stack左敦腔、上均澳、右、底四邊的距離。width和height用于指定需要定位元素的寬度和高度找前。注意糟袁,Positioned的width、height 和其它地方的意義稍微有點(diǎn)區(qū)別躺盛,此處用于配合left项戴、top 、right槽惫、 bottom來(lái)定位組件周叮,舉個(gè)例子,在水平方向時(shí)界斜,你只能指定left则吟、right、width三個(gè)屬性中的兩個(gè)锄蹂,如指定left和width后,right會(huì)自動(dòng)算出(left+width)水慨,如果同時(shí)指定三個(gè)屬性則會(huì)報(bào)錯(cuò)得糜,垂直方向同理。
示例
在下面的例子中晰洒,我們通過(guò)對(duì)幾個(gè)Text
組件的定位來(lái)演示Stack
和Positioned
的特性:
//通過(guò)ConstrainedBox來(lái)確保Stack占滿屏幕
ConstrainedBox(
constraints: BoxConstraints.expand(),
child: Stack(
alignment:Alignment.center , //指定未定位或部分定位widget的對(duì)齊方式
children: <Widget>[
Container(child: Text("Hello world",style: TextStyle(color: Colors.white)),
color: Colors.red,
),
Positioned(
left: 18.0,
child: Text("I am Jack"),
),
Positioned(
top: 18.0,
child: Text("Your friend"),
)
],
),
);
運(yùn)行效果見(jiàn)圖4-9:
由于第一個(gè)子文本組件Text("Hello world")
沒(méi)有指定定位朝抖,并且alignment
值為Alignment.center
,所以它會(huì)居中顯示谍珊。第二個(gè)子文本組件Text("I am Jack")
只指定了水平方向的定位(left
)治宣,所以屬于部分定位,即垂直方向上沒(méi)有定位砌滞,那么它在垂直方向的對(duì)齊方式則會(huì)按照alignment
指定的對(duì)齊方式對(duì)齊侮邀,即垂直方向居中。對(duì)于第三個(gè)子文本組件Text("Your friend")
贝润,和第二個(gè)Text
原理一樣绊茧,只不過(guò)是水平方向沒(méi)有定位,則水平方向居中打掘。
我們給上例中的Stack
指定一個(gè)fit
屬性华畏,然后將三個(gè)子文本組件的順序調(diào)整一下:
Stack(
alignment:Alignment.center ,
fit: StackFit.expand, //未定位widget占滿Stack整個(gè)空間
children: <Widget>[
Positioned(
left: 18.0,
child: Text("I am Jack"),
),
Container(child: Text("Hello world",style: TextStyle(color: Colors.white)),
color: Colors.red,
),
Positioned(
top: 18.0,
child: Text("Your friend"),
)
],
),
顯示效果如圖4-10所示:
可以看到,由于第二個(gè)子文本組件沒(méi)有定位尊蚁,所以fit
屬性會(huì)對(duì)它起作用亡笑,就會(huì)占滿Stack
。由于Stack
子元素是堆疊的横朋,所以第一個(gè)子文本組件被第二個(gè)遮住了仑乌,而第三個(gè)在最上層,所以可以正常顯示。