【Flutter 元件集錄】Positioned | 8 月更文挑戰

張風捷特烈發表於2021-08-24
前言:

這是我參與8月更文挑戰的第 24 天,活動詳情檢視:8月更文挑戰。為應掘金的八月更文挑戰,我準備在本月挑選 31 個以前沒有介紹過的元件,進行全面分析和屬性介紹。這些文章將來會作為 Flutter 元件集錄 的重要素材。希望可以堅持下去,你的支援將是我最大的動力~

本系列元件文章列表
1.NotificationListener2.Dismissible3.Switch
4.Scrollbar5.ClipPath6.CupertinoActivityIndicator
7.Opacity8.FadeTransition9. AnimatedOpacity
10. FadeInImage11. Offstage12. TickerMode
13. Visibility14. Padding15. AnimatedContainer
16.CircleAvatar17.PhysicalShape18.Divider
19.Flexible、Expanded 和 Spacer 20.Card21.SizedBox
22.ConstrainedBox23.Stack24.Positioned

1.認識 Positioned 元件

Positioned 元件一般只用於 Stack 元件中,原始碼中對它的介紹是:一個可以控制 Stack 子元件位置的元件。


下面是 Positioned 元件類的定義構造方法,可以看出它繼承自 ParentDataWidget<StackParentData> 。有 左上右下寬 高六個屬性。通過斷言可以看出 左右寬 不可同時為 null上下高 不可同時為 null。且 child 引數是必須傳入的。

之前介紹的 FlexibleParentDataWidget 型別的元件,它只能用於 Flex 元件中。可以看出 ParentDataWidget 可以限定元件的使用範圍。


2. Positioned 元件的使用

我們可以通過 左上右下 控制子元件相對於 Stack 元件區域的偏移量,這些數值可為負數。當超越 Stack 區域後,如果想要顯示,需要設定 clipBehavior: Clip.none ,否則出界的將會被裁剪。

class PositionedDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
          color: Colors.grey.withAlpha(33),
          constraints: BoxConstraints.tightFor(width: 200, height: 150),
          child: Stack(
            clipBehavior: Clip.none,
            children: <Widget>[
              Container(width: 100, height:100,color: Colors.red),
              Positioned(
                  left: -12,
                  top: -12,
                  child: Icon(Icons.ac_unit, color: Colors.black)),
              Positioned(
                  bottom: 20,
                  right: 10,
                  child: Icon(Icons.ac_unit, color: Colors.green))
            ],
          ),
    );
  }
}
複製程式碼

至於寬高,是用於確定 Positioned 的尺寸大小,如下將綠色圖示對應的 Positioned 寬高設定為 120*150 。可見,偏移量是根據 Positioned 的尺寸區域進行偏移的。

class PositionedDemo extends StatelessWidget {
 ... 略同
      Positioned(
          bottom: 20,
          right: 10,
          width: 120,
          height: 150,
          child: Icon(Icons.ac_unit, color: Colors.green))
    ],
複製程式碼

3.Positioned 元件的下的約束特性

下面的案例中,通過 Positioned 元件巢狀綠色,紅色不巢狀,且它們都沒有高度。想一下,紅色 Container 是否可以顯示?綠色 Container 是否可以顯示?


結果可以看出,紅色被拉伸填充,綠色不顯示。其中有著怎樣的科學道理呢?

可以看出,包裹 Positioned 元件後,由於 Container 未指定高度,高度沒有約束。

未包裹 Positioned 元件的 Container ,會受到 Stack 的約束。

通過 LayoutBuilder 可以檢視一下 Positioned 元件下的約束情況,如下,可以看出, Positioned 元件下是無約束的,這也是 Container 未指定高度,高度為 0 的根本原因。


3. Positioned 元件只能用在 Stack 中嗎?

如果 Positioned 用在別處,就會出現如下的異常:


嚴格意義上來說,Positioned 並不是只能用在 Stack 元件內。決定Positioned 元件可以用在 Stack 元件下的本質原因是 RenderStack 混入了 ContainerRenderObjectMixin<RenderBox, StackParentData>

也就是說,如果別的渲染物件混入了 ContainerRenderObjectMixin<RenderBox, StackParentData> ,其內部也是可以用 Positioned 元件的。比如 _RenderTheatre ,這個渲染物件對應的元件是 _Theatre。用於 Overlay 元件中。

也就是說在 Overlay 元件中,我們也可以使用 Positioned 元件進行定位。那本文到這裡就結束了,謝謝觀看,明天見~

相關文章