小菜對限制 Box 探索之路還在繼續,小菜今天主要學習一下 Overflow 相關 Box;
OverflowBox
源碼分析
class OverflowBox extends SingleChildRenderObjectWidget {
const OverflowBox({
Key key,
this.alignment = Alignment.center, // 對齊方式
this.minWidth, // 允許最小寬度
this.maxWidth, // 允許最大寬度
this.minHeight, // 允許最小高度
this.maxHeight, // 允許最大高度
Widget child,
})
}
分析源碼可得,OverflowBox 通過設定最大最小寬高對子 Widget 進行限制,且與父 Widget 相關,子 Widget 可能會溢出父 Widget;
案例嘗試
小菜通過如下幾種場景探索 OverflowBox 與父 Widget 和子 Widget 的關聯關系,其中 alignment 是通用的對齊方式,不在此單獨說明;由于 OverflowBox 允許子 Widget 溢出父 Widget,很多朋友用此實作自定義 Dialog;
- 父 Widget 無限制,僅設定 minWidth / minHeight,子 Widget 寬高小于等于 OverflowBox 最小寬高;此時 child.width <= minWidth && child.height <= minHeight,最終以 OverflowBox 設定的最小寬高限制子 Widget;
return Container(color: Colors.blueAccent.withOpacity(0.4),
child: OverflowBox(alignment: Alignment.center, minHeight: 100,
child: Container(color: Colors.purple.withOpacity(0.4), width: 50, height: 50)));

- 父 Widget 無限制,僅設定 minWidth / minHeight,子 Widget 寬高大于 OverflowBox 最小寬高;此時 minWidth < child.width < maxWidth,最終以子 Widget 設定的寬高展示;
return Container(color: Colors.green.withOpacity(0.4),
child: OverflowBox(alignment: Alignment.center, minHeight: 100, minWidth: 100,
child:Container(color: Colors.purple.withOpacity(0.4), width: 150, height: 150)));
- 父 Widget 無限制,設定 maxWidth / maxHeight,若 child.width > maxWidth || child.height > maxHeight 則以 OverflowBox 設定的最大寬高限制子 Widget;若 child.width < maxWidth && child.height < maxHeight 則按照上述兩種情況進行限制;
return Container(color: Colors.orange.withOpacity(0.4),
child: OverflowBox(alignment: Alignment.center,
minHeight: 100, maxWidth: 150, maxHeight: 150,
child: Container(color: Colors.purple.withOpacity(0.4), width: 50, height: 50)));
return Container(color: Colors.grey.withOpacity(0.4),
child: OverflowBox(alignment: Alignment.center,
minHeight: 100, minWidth: 100, maxWidth: 150, maxHeight: 150,
child: Container(color: Colors.purple.withOpacity(0.4), width: 200, height: 200)));
- 父 Widget 有限制,設定 maxWidth > parent.width || maxHeight > parent.height,此時允許子 Widget 寬高大于父 Widget 寬高,其限制方式與上述情況相同;
return Container(width: 200, height: 200, color: Colors.brown.withOpacity(0.4),
child: OverflowBox(alignment: Alignment.center,
minHeight: 100, minWidth: 50, maxHeight: 250, maxWidth: 250,
child: Container(color: Colors.purple.withOpacity(0.4))));
- 對于大部分涉及最大最小寬高的 Widget,最小寬高均不允許大于最大寬高,使用時請注意;
return Container(width: 200, height: 200, color: Colors.brown.withOpacity(0.4),
child: OverflowBox(alignment: Alignment.center,
minHeight: 250, minWidth: 50,
child: Container(color: Colors.purple.withOpacity(0.4))));
SizedOverflowBox
class SizedOverflowBox extends SingleChildRenderObjectWidget {
const SizedOverflowBox({
Key key,
@required this.size, // 限制 Size
this.alignment = Alignment.center, // 對齊方式
Widget child,
})
}
分析源碼可知,SizedOverflowBox 是 SizedBox 與 OverflowBox 的結合,小菜簡單了解 SizedBox 設定基本限制,OverflowBox 設定子 Widget 與父 Widget 關系,是否溢出;
size 是對子 Widget 的基本尺寸限制,alignment 是通用的對齊方式,小菜按如下場景進行嘗試;
- 父 Widget 無限制,若 child.width <= Size.x && child.height <= Size.y,以子 Widget 寬高限制展示;
return Container(color: Colors.green.withOpacity(0.4),
child: Center(child: SizedOverflowBox(
size: Size(100, 100), alignment: Alignment.center,
child: Container(width: 50, height: 50, color: Colors.blueAccent.withOpacity(0.6)))));
- 父 Widget 無限制,若 child.width > Size.x || child.height > Size.h,以子 Widget 寬高溢出展示;
return Container(color: Colors.orange.withOpacity(0.4),
child: Center(child: SizedOverflowBox(
size: Size(100, 100), alignment: Alignment.center,
child: Container(width: 150, height: 150, color: Colors.purple.withOpacity(0.4)))));
- 父 Widget 有限制時,若 child.width <= Size.x && child.height <= Size.y 時,與狀況一相同;若 child.width > parent.width >= Size.x || child.height > parent.height >= Size.y,則子 Widget 溢出 SizedOverflowBox 到父 Widget 限制寬高展示;
return Container(width: 150, height: 150, color: Colors.redAccent.withOpacity(0.4),
child: Center(child: SizedOverflowBox(
size: Size(100, 100), alignment: Alignment.center,
child: Container(width: 250, height: 50, color: Colors.grey.withOpacity(0.8)))));
- 父 Widget 有限制時,若 Size.x > parent.width || Size.y > parent.height,最終展示的最大寬高是父 Widget 限制的寬高(子 Widget 溢出或非溢出);
return Container(width: 150, height: 150, color: Colors.redAccent.withOpacity(0.4),
child: Center(child: SizedOverflowBox(
size: Size(400, 400), alignment: Alignment.topLeft,
child: Container(width: 150, height: 50, color: Colors.grey.withOpacity(0.8)))));
小了解
小菜嘗試了諸多限制 Box,甚至有些 Box 在使用和功能上大同小異,相同的功能,可以用其他的 Widget 來實作但為什麼要有這麼多限制 Box?
小菜對此了解還不夠深入,僅簡單的交流個人了解,如有錯誤請多多指導!對于常用的 SizedBox 既可以用作限制盒子也可以作為空間占位符,對此 Container 完全可以實作,還可以實作很多複雜效果;SizedBox 存在的理由:小菜認為一是 SizedBox 功能更單一,相對于 Container 性能更好(Flutter 渲染性能很高,可以忽略不計);二是 SizedBox 功能性更加清晰明确;合理利用各 Widget 會讓編碼更加清晰高效;
小菜對限制 Box 的探索暫時到此,希望大家可以對各類 Box 多多嘗試!
來源: 阿策小和尚