Flutter實(shí)戰(zhàn) 層疊布局 Stack、Positioned

2021-03-08 10:02 更新

層疊布局和 Web 中的絕對定位、Android 中的 Frame 布局是相似的,子組件可以根據(jù)距父容器四個角的位置來確定自身的位置。絕對定位允許子組件堆疊起來(按照代碼中聲明的順序)。Flutter 中使用StackPositioned這兩個組件來配合實(shí)現(xiàn)絕對定位。Stack允許子組件堆疊,而Positioned用于根據(jù)Stack的四個角來確定子組件的位置。

#Stack

Stack({
  this.alignment = AlignmentDirectional.topStart,
  this.textDirection,
  this.fit = StackFit.loose,
  this.overflow = Overflow.clip,
  List<Widget> children = const <Widget>[],
})

  • alignment:此參數(shù)決定如何去對齊沒有定位(沒有使用Positioned)或部分定位的子組件。所謂部分定位,在這里特指沒有在某一個軸上定位:leftright為橫軸,topbottom為縱軸,只要包含某個軸上的一個定位屬性就算在該軸上有定位。
  • textDirection:和Row、WraptextDirection功能一樣,都用于確定alignment對齊的參考系,即:textDirection的值為TextDirection.ltr,則alignmentstart代表左,end代表右,即從左往右的順序;textDirection的值為TextDirection.rtl,則alignment的start代表右,end代表左,即從右往左的順序。
  • fit:此參數(shù)用于確定沒有定位的子組件如何去適應(yīng)Stack的大小。StackFit.loose表示使用子組件的大小,StackFit.expand表示擴(kuò)伸到Stack的大小。
  • overflow:此屬性決定如何顯示超出Stack顯示空間的子組件;值為Overflow.clip時,超出部分會被剪裁(隱藏),值為Overflow.visible 時則不會。

#Positioned

const Positioned({
  Key key,
  this.left, 
  this.top,
  this.right,
  this.bottom,
  this.width,
  this.height,
  @required Widget child,
})

lefttop 、rightbottom分別代表離Stack左、上、右、底四邊的距離。widthheight用于指定需要定位元素的寬度和高度。注意,Positionedwidth、height 和其它地方的意義稍微有點(diǎn)區(qū)別,此處用于配合lefttop 、right、 bottom來定位組件,舉個例子,在水平方向時,你只能指定leftright、width三個屬性中的兩個,如指定leftwidth后,right會自動算出(left+width),如果同時指定三個屬性則會報錯,垂直方向同理。

#示例

在下面的例子中,我們通過對幾個Text組件的定位來演示StackPositioned的特性:

//通過ConstrainedBox來確保Stack占滿屏幕
ConstrainedBox(
  constraints: BoxConstraints.expand(),
  child: Stack(
    alignment:Alignment.center , //指定未定位或部分定位widget的對齊方式
    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)行效果見圖4-9:

圖4-9

由于第一個子文本組件Text("Hello world")沒有指定定位,并且alignment值為Alignment.center,所以它會居中顯示。第二個子文本組件Text("I am Jack")只指定了水平方向的定位(left),所以屬于部分定位,即垂直方向上沒有定位,那么它在垂直方向的對齊方式則會按照alignment指定的對齊方式對齊,即垂直方向居中。對于第三個子文本組件Text("Your friend"),和第二個Text原理一樣,只不過是水平方向沒有定位,則水平方向居中。

我們給上例中的Stack指定一個fit屬性,然后將三個子文本組件的順序調(diào)整一下:

Stack(
  alignment:Alignment.center ,
  fit: StackFit.expand, //未定位widget占滿Stack整個空間
  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所示:

圖4-10

可以看到,由于第二個子文本組件沒有定位,所以fit屬性會對它起作用,就會占滿Stack。由于Stack子元素是堆疊的,所以第一個子文本組件被第二個遮住了,而第三個在最上層,所以可以正常顯示。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號