全網最詳細的一篇Flutter 尺寸限制類容器總結
- 2020 年 3 月 5 日
- 筆記
Flutter中尺寸限制類容器組件包括ConstrainedBox、UnconstrainedBox、SizedBox、AspectRatio、FractionallySizedBox、LimitedBox、Container。這些組件可以約束子組件的尺寸,下面一一介紹。
ConstrainedBox
ConstrainedBox組件約束子組件的最大寬高和最小寬高,假如一個組件寬高都是300,包裹在ConstrainedBox中,並給ConstrainedBox添加最大寬高約束,用法如下:
ConstrainedBox( constraints: BoxConstraints(maxHeight: 60, maxWidth: 200), child: Container(height: 300, width: 300, color: Colors.red), )
這時子組件是無法突破BoxConstraints設置的最大寬高,效果如下:
BoxConstraints的默認值如下:
const BoxConstraints({ this.minWidth = 0.0, this.maxWidth = double.infinity, //無限大 this.minHeight = 0.0, this.maxHeight = double.infinity, //無限大 });
BoxConstraints提供了便捷的構建函數,方便開發者調用,如BoxConstraints.tight(Size size)
和BoxConstraints.expand()
等。
如果BoxConstraints嵌套使用,有2個ConstrainedBox,如下:
ConstrainedBox( constraints: BoxConstraints(maxHeight: 60, maxWidth: 200), child: ConstrainedBox( constraints: BoxConstraints(maxHeight: 100, maxWidth: 240), child: Container(height: 300, width: 300, color: Colors.red), ), )
以最大寬為例,第一個BoxConstraints的maxHeight
值是60,也就是約束其子控件最大高是60,第二個BoxConstraints的maxHeight
值是100,由於第二個BoxConstraints也受第一個的約束,所以第二個BoxConstraints最大高也只能是60,最終子組件的最大高是60,同理最大寬是200,因此多級BoxConstraints嵌套約束最大值最終值等於多個BoxConstraints約束中的最小值。同理嵌套約束最小值等於多個BoxConstraints約束中的最大值。
UnconstrainedBox
UnconstrainedBox組件不對子組件做任何約束,比如有一個父組件大小是200×200,子組件是UnconstrainedBox,UnconstrainedBox包裹一個300×300的組件,代碼如下:
Container( height: 200, width: 200, child: UnconstrainedBox( child: Container(height: 300, width: 300, color: Colors.red), ), )
效果如下:
注意:黃色區域表示子控件超出父控件的區域了,黃色區域只會在debug模式下存在,在release模式下,只有紅色區域。
UnconstrainedBox雖然不限制其子控件的大小,但仍然受父控件的約束,超出父控件的區域將會截取。
UnconstrainedBox允許設置對齊方式,用法如下:
UnconstrainedBox( alignment: Alignment.topLeft, ... )
效果如下:
和上一個圖對比,這次左邊和上邊沒有超出區域,右邊和下邊各超出100px。
SizedBox
SizedBox是具有固定寬高的組件,直接指定具體的寬高,用法如下:
SizedBox( height: 60, width: 200, child: RaisedButton( child: Text('this is SizedBox'), ), )
我們也可以設置尺寸無限大,如下:
SizedBox( height: double.infinity, width: double.infinity, ... )
雖然設置了無限大,子控件是否會無限長呢?不,不會,子控件依然會受到父組件的約束,會擴展到父組件的尺寸,還有一個便捷的方式設置此方式:
SizedBox.expand( child: RaisedButton( child: Text('this is SizedBox'), ), )
SizedBox可以沒有子組件,但仍然會佔用空間,所以SizedBox非常適合控制2個組件之間的空隙,用法如下:
Column( children: <Widget>[ Container(height: 30,), SizedBox(height: 10,), Container(height: 30,), ], )
AspectRatio
AspectRatio組件是固定寬高比的組件,如果組件的寬度固定,希望高是寬的1/2,可以用AspectRatio實現此效果,用法如下:
AspectRatio( aspectRatio: 2 / 1, child: Container(color: Colors.red), )
aspectRatio
參數是寬高比,可以直接寫成分數的形式,也可以寫成小數的形式,但建議寫成分數的形式,可讀性更高。效果如下:
FractionallySizedBox
當我們需要一個控件的尺寸是相對尺寸時,比如當前按鈕的寬度占父組件的70%,可以使用FractionallySizedBox來實現此效果。
使用FractionallySizedBox包裹子控件,設置widthFactor
寬度係數或者heightFactor
高度係數,係數值的範圍是0-1,0.7表示占父組件的70%,用法如下:
FractionallySizedBox( widthFactor: .7, child: RaisedButton( child: Text('button'), ), )
通過alignment
參數控制子組件顯示的位置,默認為center
,用法如下:
FractionallySizedBox( alignment: Alignment.centerLeft, ... )
如果想讓2個控件之間的間隔是當前父控件的10%,可以使用無子控件的FractionallySizedBox,用法如下:
Container( height: 200, color: Colors.grey, child: Column( children: <Widget>[ Container( height: 50, color: Colors.red, ), Flexible( child: FractionallySizedBox( heightFactor: .1, ), ), Container( height: 50, color: Colors.blue, ), ], ), )
效果如下:
LimitedBox
LimitedBox組件是當不受父組件約束時限制它的尺寸,什麼叫不受父組件約束?就像這篇文章介紹的其他組件,它們都會對子組件約束,沒有約束的父組件有ListView、Row、Column等,如果LimitedBox的父組件受到約束,此時LimitedBox將會不做任何操作,我們可以認為沒有這個組件,代碼如下:
Container( height: 100, width: 100, child: LimitedBox( maxHeight: 50, maxWidth: 100, child: Container(color: Colors.green,), ), )
效果如下:
LimitedBox設置的寬高不是正方形,此時效果時正方形,說明LimitedBox沒有起作用。
在ListView中直接添加Container組件,如下:
ListView( children: <Widget>[ Container( color: Colors.green, ), Container( color: Colors.red, ), ], )
這時你會發現什麼也沒有,因為在容器不受約束時,大小將會設置0,只需將Container包裹在LimitedBox中即可:
ListView( children: <Widget>[ LimitedBox( maxHeight: 100, child: Container( color: Colors.green, ), ), LimitedBox( maxHeight: 100, child: Container( color: Colors.red, ), ), ], )
效果:
Container
Container組件應該是最常用的組件之一,Container組件可以直接設置其寬高,用法如下:
Container( height: 100, width: 100, ... )
Container組件是這些組件裏面屬性最多的一個,當然也是用法最複雜的一個,這裡重點介紹Container對子組件的約束,我在前面的文章中已經詳細的介紹了Container,這裡不在介紹,奉上跳轉地址:https://blog.csdn.net/mengks1987/article/details/104388393
總結
這麼多約束類的容器組件,到底要使用哪一個組件呢?總結如下:
- ConstrainedBox:適用於需要設置最大/小寬高,組件大小以來子組件大小,但不能超過設置的界限。
- UnconstrainedBox:用到情況不多,當作ConstrainedBox的子組件可以「突破」ConstrainedBox的限制,超出界限的部分會被截取。
- SizedBox:適用於固定寬高的情況,常用於當作2個組件之間間隙組件。
- AspectRatio:適用於固定寬高比的情況。
- FractionallySizedBox:適用於占父組件百分比的情況。
- LimitedBox:適用於沒有父組件約束的情況。
- Container:適用於不僅有尺寸的約束,還有裝飾(顏色、邊框、等)、內外邊距等需求的情況。
今天的文章對大家是否有幫助?如果有,請在文章底部留言和點贊,以表示對我的支持,你們的留言、點贊和轉發關注是我持續更新的動力!
更多相關閱讀:
- Flutter系列文章總覽
- Flutter Widgets 之 ListWheelScrollView
- Flutter DataTable 看這一篇就夠了
- Flutter Widgets 之 PageView