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

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

這是我參與8月更文挑戰的第 25 天,活動詳情檢視: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
25.OverflowBox

1.認識 OverflowBox 元件

我們都知道,一般佈局元件,由於父區域的約束,其子節點區域都會被限制在內父區域之內。但有時我們有需求讓子元件脫離區域限制,溢位父區域。而這就是 OverflowBox 的價值所在。原始碼中的介紹是: 讓元件的約束有別於父節點的約束,可以允許元件溢位父部件。

下面是 OverflowBox 元件類的定義構造方法,可以看出它繼承自 SingleChildRenderObjectWidget 。可以設定寬高區域及對其方式。


2. OverflowBox 元件的使用

在說 OverflowBox 之前,先看一下常規的盒約束。如下程式碼中,父親 SizedBox 尺寸為 100*100 ,按照約束正常的傳遞,孩子 SizedBox 雖然想要 200*50 區域,但卻不能突破父親約束的顯示。如下,第二個 SizedBox100*100 的強約束下,尺寸被定為 100*100

class OverflowBoxDemo extends StatelessWidget{
  @override
  Widget build(BuildContext context) {

    return SizedBox(
            width: 100,
            height: 100,
            child: buildBox()
    );
  }

  Widget buildBox() {
    return SizedBox(
          width: 200,
          height: 50,
      );
  }
}
複製程式碼

你如何讓子 SizedBox 突破限制呢,如下通過 OverflowBox 設定一個 200*50 的強約束。這樣子 SizedBox 則會按照 OverflowBox 施加的約束進行佈局。從效果上來看,子 SizedBox 就突破了外層約束的限制。

Widget buildBox() {
  return OverflowBox(
    minHeight: 50,
    minWidth: 200,
    maxWidth: 200,
    maxHeight: 50,
    child: SizedBox(
          width: 200,
          height: 50,
      ),
  );
}
複製程式碼

3.OverflowBox 的 alignment 屬性

alignment 代表對齊方式,預設情況下是Alignment.center,比如上圖中,子 SizedBox 是以和外界區域中心對齊的。如下是 Alignment.topLeft 也就是左上角進行對其。

OverflowBox(
  alignment: Alignment.topLeft,
  minHeight: 50,
  minWidth: 200,
  maxWidth: 200,
  maxHeight: 50,
  child: SizedBox(
        width: 200,
        height: 50,
    ),
);
複製程式碼

Alignment.topCenter 效果如下,也就是說 OverflowBox 不僅可以允許子元件越界,還可以指定子元件相對於外層區域的對齊方式。通過三個方位對比,你應該明白 alignment 的作用了吧。


通過 OverflowBox 元件就可以很容易處理子元件越界的需求,如下,紅色元件越出了藍色區域,大家可以自己試一下。另外說明一點: 通過OverflowBox 越界的部分,無法響應點選事件。


4. OverflowBox 的原始碼實現

OverflowBox 繼承自 SingleChildRenderObjectWidget ,內部維護 RenderConstrainedOverflowBox 物件來實現功能。

實現的原理也很簡單,下面紅框中的 constraintsRenderConstrainedOverflowBox 自身的約束,可以看到在 _getInnerConstraints 中會生成新的約束,如果幾個引數都設定了,入參的 constraints 就是無用的,也就說明 RenderConstrainedOverflowBox 其實是忽略了上層約束,用新約束來約束孩子。

打個比方:

---->[場景一]----
孩子: 爸,給我 100 塊,買玩具。
父親: 我只有 50 塊,拿去滾蛋。

---->[場景二]----
孩子: 爸,給我 100 塊,買玩具。
父親: 我只有 50 塊,拿去滾蛋。
母親: 別介,我有 100 塊, 孩子你拿去吧。
父親: 孩子他媽,那這 50 你拿著。
複製程式碼

可以看出 OverflowBox 的本質就是重新對孩子的區域進行限定 ,而脫離 原本約定區域的限定。但 OverflowBox 本身會是被 原本約定區域限定 。它也算是李代桃僵,成全 child 的 "放肆"。

那本文到這裡就結束了,謝謝觀看,明天見~

相關文章