瞭解Flutter Widget前,你需要先理解這些前置知識
初學flutter基礎widget時,如Container Widget,查閱官方文件時,經常會碰到
to size itself to thechild, to honor thewidth
,height
, andconstraints, to expand to fit the parent, to be as small as possible.
我們有必要了解:
- 什麼是Constraints(約束)?
- Flutter中有幾種Constraints子類?
- Constraints與Widget Size 的關聯?
- BoxConstraints的型別?
- BoxConstraints的作用?
什麼是Constraints(約束)?
An abstract set of layout constraints. Concrete layout models (such as box) will create concrete subclasses to communicate layout constraints between parents and children.
Constraints是抽象佈局約束類,
具體的佈局模型需要建立對應的Constraints子類,用來傳遞父Widget與子Widget之間的佈局約束;
Flutter中有幾種Constraints子類?
通過檢視flutter程式碼,目前Flutter中有兩個Constraints子類,( 以後估計會有更多子類)BoxConstraints和SliverConstraints,根據Constraints的說明,BoxConstraints是專為Box佈局模型建立的,SilverConstraints是專為Silver佈局模型建立的, 我們只需知道,前者用於顯示在2D(笛卡爾座標系中的)物件,後者用於顯示對滾動做出反應的物件,具體這兩種佈局模型的區別,後續文章再述;我們先看下BoxConstraints:
BoxConstraints有maxWidth,minWidth,maxHeight,minHeight四個成員變數,且BoxConstraints需要滿足:
-
0.0 <=minWidth <=maxWidth <=double.infinity
-
0.0 <=minHeight <=maxHeight <=double.infinity
double.infinity在此處表示無窮大;
Constraints與Widget Size 的關聯?
Widget結點的大小(size:由指定的width和height組成)會遵循父結點傳遞給它的約束(Constraints),但是要求其滿足以下條件:
-
minWidth <=Size.width <=maxWidth
-
minHeight <=Size.height <=maxHeight
BoxConstraints的型別?
-
tight constraints(緊密約束):
指的是這些約束嚴格地限定了渲染物件確認大小(Size)時的可選餘地(當constraints的minWidth等於maxWidth時,這種情況下,我們稱這個約束有緊密寬度),例如MaterialApp Widget(flutter 提供的應用框架),會被傳遞緊密約束以直充滿整個手機螢幕(根據不同的手機螢幕,會有不同的具體值);
-
loosen constraints(寬鬆約束):
與緊密約束相比,寬鬆約束只會限定maxWidth或者maxHeight的值,minWidth或者minHeight的值為0;
-
bounded constraints(有邊界約束):
constraints中的maxWidth或者maxHeight小於double.infinity
bool get hasBoundedWidth => maxWidth < double.infinity;
bool get hasBoundedHeight => maxHeight < double.infinity;
-
unbounded constraints(無邊界約束):
constraints中的maxWidth或者maxHeight的值為double.infinity
-
expending constraints(擴充套件約束):
constraints中的maxWidth,maxHeight,minWidth,minHeight都為double.infinity;
Constraints的作用?
在Flutter中,widget只會儲存一些基本資訊,具體的渲染由RenderBox物件完成,RenderBox由其父級給出約束,並根據這些約束自行調整自身大小;具體來說,Flutter框架中的佈局模型是由一個個RenderBox物件排列組成的樹形結構,從該樹狀模型的根結點開始渲染,向子結點傳遞約束,這些約束會被傳遞到最終子結點,並從最終子結點返回根結點,返回過程中,子結點會根據接收到的約束調整自身大小,並將此大小(Size)向上傳遞給父結點:
1,父結點A向每個子結點傳遞constraints,子結點的最終佈局需要遵守這些約束,就像小時候出門玩,父母跟你的約定,你可以隨便玩,但是6點前必須回家吃飯;
2,子結點B1,B2可以有自己的約束,同時B1也向它的子結點C傳遞該限制,直到C沒有子結點為止,當你長大成家了,你也讓你的孩子6點前必須回家吃飯
3,子結點B1可以根據接收來自父結點A的約束,自身的情況(width,height),子結點C上傳過來的Size這三個因素來確定自身大小(Size),收集完這些佈局資訊之後,子結點B就可以把這些資訊向上傳給結點A;
對於Box模型(Box Model),由父結點向下傳遞給子結點的約束稱為盒約(BoxConstraints),它決定了允許其子結點可佔用的最大、最小寬度和最大最小高度,比如下圖是父結點傳遞給子結點的盒約束,意味著子結點可以任意佔用綠色框內大小,即:子結點的寬度介於150和300之間,高度介於100和無窮大(infinity),然後子結點在滿足父結點的約束和自身需佔用的大小等因素確認最終大小(Size),並通知其父結點;
結語:
本篇梳理了Flutter的一些佈局及相關術語,下篇將會進入Flutter Widget Container的詳解,Container與本篇中提及的知識點結合比較緊,是充分理解Container的必要基礎知識。