## 層疊布局
層疊布局和Web中的絕對定位、Android中的Frame布局是相似的,子widget可以根據到父容器四個角的位置來確定本身的位置。絕對定位允許子widget堆疊(按照代碼中聲明的順序)。Flutter中使用Stack和Positioned來實現絕對定位,Stack允許子widget堆疊,而Positioned可以給子widget定位(根據Stack的四個角)。
### Stack
```
Stack({
this.alignment = AlignmentDirectional.topStart,
this.textDirection,
this.fit = StackFit.loose,
this.overflow = Overflow.clip,
List<Widget> children = const <Widget>[],
})
```
- alignment:此參數決定如何去對齊沒有定位(沒有使用Positioned)或部分定位的子widget。所謂部分定位,在這里**特指沒有在某一個軸上定位:**left、right為橫軸,top、bottom為縱軸,只要包含某個軸上的一個定位屬性就算在該軸上有定位。
- textDirection:和Row、Wrap的textDirection功能一樣,都用于決定alignment對齊的參考系即:textDirection的值為`TextDirection.ltr`,則alignment的`start`代表左,`end`代表右;textDirection的值為`TextDirection.rtl`,則alignment的`start`代表右,`end`代表左。
- fit:此參數用于決定**沒有定位**的子widget如何去適應Stack的大小。`StackFit.loose`表示使用子widget的大小,`StackFit.expand`表示擴伸到Stack的大小。
- overflow:此屬性決定如何顯示超出Stack顯示空間的子widget,值為`Overflow.clip`時,超出部分會被剪裁(隱藏),值為`Overflow.visible` 時則不會。
### 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用于指定定位元素的寬度和高度,注意,此處的width、height 和其它地方的意義稍微有點區別,此處用于配合left、top 、right、 bottom來定位widget,舉個例子,在水平方向時,你只能指定left、right、width三個屬性中的兩個,如指定left和width后,right會自動算出(left+width),如果同時指定三個屬性則會報錯,垂直方向同理。
### 示例
```
//通過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"),
)
],
),
);
```
運行效果如下:

由于第一個子widget Text("Hello world")沒有指定定位,并且alignment值為`Alignment.center`,所以,它會居中顯示。第二個子widget Text("I am Jack")只指定了水平方向的定位(left),所以屬于部分定位,即垂直方向上沒有定位,那么它在垂直方向對齊方式則會按照alignment指定的對齊方式對齊,即垂直方向居中。對于第三個子widget Text("Your friend"),和第二個Text原理一樣,只不過是水平方向沒有定位,則水平方向居中。
我們給上例中的Stack指定一個fit屬性,然后將三個子widget的順序調整一下:
```
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"),
)
],
),
```
顯示效果如下:

可以看到,由于第二個子widget沒有定位,所以`fit`屬性會對它起作用,就會占滿Stack。有Stack子元素是堆疊的,所以第一個子Widget被第二個遮住了,而第三個在最上層,所以可以正常顯示。
- 緣起
- 起步
- 移動開發技術簡介
- Flutter簡介
- 搭建Flutter開發環境
- 常見配置問題
- Dart語言簡介
- 第一個Flutter應用
- 計數器示例
- 路由管理
- 包管理
- 資源管理
- 調試Flutter APP
- Dart線程模型及異常捕獲
- 基礎Widgets
- Widget簡介
- 文本、字體樣式
- 按鈕
- 圖片和Icon
- 單選框和復選框
- 輸入框和表單
- 布局類Widgets
- 布局類Widgets簡介
- 線性布局Row、Column
- 彈性布局Flex
- 流式布局Wrap、Flow
- 層疊布局Stack、Positioned
- 容器類Widgets
- Padding
- 布局限制類容器ConstrainedBox、SizeBox
- 裝飾容器DecoratedBox
- 變換Transform
- Container容器
- Scaffold、TabBar、底部導航
- 可滾動Widgets
- 可滾動Widgets簡介
- SingleChildScrollView
- ListView
- GridView
- CustomScrollView
- 滾動監聽及控制ScrollController
- 功能型Widgets
- 導航返回攔截-WillPopScope
- 數據共享-InheritedWidget
- 主題-Theme
- 事件處理與通知
- 原始指針事件處理
- 手勢識別
- 全局事件總線
- 通知Notification
- 動畫
- Flutter動畫簡介
- 動畫結構
- 自定義路由過渡動畫
- Hero動畫
- 交錯動畫
- 自定義Widget
- 自定義Widget方法簡介
- 通過組合現有Widget實現
- 實例:TurnBox
- CustomPaint與Canvas
- 實例:圓形漸變進度條(自繪)
- 文件操作與網絡請求
- 文件操作
- Http請求-HttpClient
- Http請求-Dio package
- 實例:Http分塊下載
- WebSocket
- 使用Socket API
- Json轉Model
- 包與插件
- 開發package
- 插件開發:平臺通道簡介
- 插件開發:實現Android端API
- 插件開發:實現IOS端API
- 系統能力調用
- 國際化
- 讓App支持多語言
- 實現Localizations
- 使用Intl包
- Flutter核心原理
- Flutter UI系統
- Element和BuildContext
- RenderObject與RenderBox
- Flutter從啟動到顯示