前言:
這是我參與8月更文挑戰的第 26 天,活動詳情檢視:8月更文挑戰。為應掘金的八月更文挑戰
,我準備在本月挑選 31
個以前沒有介紹過的元件,進行全面分析和屬性介紹。這些文章將來會作為 Flutter 元件集錄
的重要素材。希望可以堅持下去,你的支援將是我最大的動力~
1.認識 SizedOverflowBox 元件
從原始碼的介紹中可以看出 SizedOverflowBox
元件的特點是:
-
- 它可以指定自身特定的尺寸
-
- 它會將原始的約束傳遞給孩子
-
- 它的孩子可以溢位
上一篇介紹的 OverflowBox 元件也可以允許子元件溢位,他們最大的區別在於: OverflowBox
會指定新約束傳遞給孩子,而 SizedOverflowBox
則將原始約束傳遞給孩子。
下面是 SizedOverflowBox
元件類的定義
和 構造方法
,可以看出它繼承自 SingleChildRenderObjectWidget
。構造時必須傳入尺寸 size
引數,並且可以指定對齊方式。
2.SizedOverflowBox 元件的使用
如下,在一個灰色盒子左上角,有一個小紅圈,其中心與盒子左上角對齊。可以看出在效果上,小紅圈 溢位
了灰色盒子的區域。實現方式是,灰色盒子內部對齊方式 Alignment.topLeft
,SizedOverflowBox
對齊方式 Alignment.center
。
class CustomSizedOverflowBox extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.topLeft,
color: Colors.grey.withAlpha(88),
width: 50,
height: 50,
child: buildChild(),
);
}
Widget buildChild() {
return SizedOverflowBox(
alignment: Alignment.center,
size: Size.zero,
child: Container(
decoration: const BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
width: 15,
height: 15,
),
);
}
}
複製程式碼
通過佈局可以檢視 SizedOverflowBox
的區域資訊,如下為 Size(0,0)
,也就是構造時我們傳入的尺寸。
當 size
設定為 Size(30,25)
時,效果如下。可見指定的尺寸值就是 SizedOverflowBox
的尺寸,而 SizedOverflowBox
的 alignment
屬性就是其內部的對齊方式。
SizedOverflowBox(
alignment: Alignment.center,
size: Size(30,25),
//略同...
);
複製程式碼
下面是 SizedOverflowBox#alignment
為 Alignment.topLeft
的效果,可以看出小紅球在與左上角對齊。這就是 SizedOverflowBox
的 alignment
和 size
兩個屬性的作用。
SizedOverflowBox(
alignment: Alignment.topLeft,
size: Size(30,25),
//略同...
);
複製程式碼
3. SizedOverflowBox 約束分析
首先 SizedOverflowBox
會受父級的約束,比如上面的 Container
會施加 [w(50,50) - h(50,50)]
的緊約束,但由於設定了 Container#alignment
屬性,內部會使用 Align
元件。這會讓 SizedOverflowBox
的約束變為了 [w(0,50) - h(0,50)]
的鬆散約束,此時 SizedOverflowBox
申請的尺寸為 30*25
,滿足約束,則其尺寸為 30*25
。
如果去除了 Container#alignment
屬性, [w(50,50) - h(50,50)]
的強約束會直接施加到 SizedOverflowBox
上,即使申請的尺寸為 30*25
,其尺寸也會變為 50*50
。這也間接可以產出 Align
元件可以起到鬆散約束的效果。
SizedOverflowBox
的特點是:它的約束會直接傳遞給孩子,不做任何改動。可以看出 Align
施加給 SizedOverflowBox
的 [w(0,50) - h(0,50)]
鬆散約束,會直接傳給小紅點。也就是說,雖然小紅點可以越界,但它的尺寸仍會受到外層的約束。
SizedOverflowBox
會將自身受到的約束,直接傳遞給孩子,這也能解釋為什麼去除了 Container#alignment
屬性,SizedOverflowBox
尺寸為 50*50
小紅點尺寸也是 50*50
。
即使小紅點尺寸申請為 150*150
,由於 [w(0,50) - h(0,50)]
的約束,自身尺寸也將被限制。
4.SizedOverflowBox 原始碼實現
SizedOverflowBox
繼承自 SingleChildRenderObjectWidget
,內部維護 RenderSizedOverflowBox
渲染物件來實現功能。
可以看出入參的尺寸會為 _requestedSize
屬性賦值。
在 performLayout
中,通過當前約束
和請求尺寸
,來決定 RenderSizedOverflowBox
的尺寸。這個渲染物件非常特別,一般來說都是約束
x 向下傳遞給子節點進行佈局,之後子節點向上反饋尺寸。而這裡是先確定父節點的尺寸,也就表明它的尺寸並不受子渲染物件影響。如果 child
非空,會對自渲染物件進行佈局,傳入的是自身的原始約束
。
那本文到這裡就結束了,謝謝觀看,明天見~