在Flutter中,widget由其底層的RenderBox對象渲染。 渲染框由它們的父級給出約束,并且在這些約束下調(diào)整自身大小。約束由最小寬度、最大寬度和高度組成; 尺寸由特定的寬度和高度組成。
通常,按照widget如何處理他們的約束來看,有三種類型的盒子:
一些widget,例如Container, 會根據(jù)構(gòu)造函數(shù)參數(shù)的不同而不同。Container默認(rèn)是盡可能大的占用空間, 但是如果你給它指定一個width,那它就會采用指定的值。
其他一些,例如Row 和 Column (flex boxes) 會根據(jù)給定它們的約束的不同而不同,如下面的“Flex”部分所述。
這些約束有時是“tight”,這意味著它們沒有留下讓渲染框自己決定大小的空間(例如,如果最小和最大寬度相同,也就是說有一個tight寬度)。 其中的主要例子是App widget, 它是RenderView類包含的一個widget :由應(yīng)用程序build函數(shù)返回的子widget的渲染框被指定了一個約束,強(qiáng)制它精確填充應(yīng)用程序的內(nèi)容區(qū)域(通常是整個屏幕)。 Flutter中的許多盒子,特別是那些只包含一個子widget的,都會將其約束傳遞給他們的孩子。 這意味著如果您在應(yīng)用程序的渲染樹的根部嵌套一些盒子,那么子節(jié)點(diǎn)都要受到這些渲染盒的約束。
有些箱子放松了約束,有“最大”約束,但沒有“最小”約束。例如,Center。
在某些情況下,渲染盒的約束將是無邊界(unbounded)的或無限的。這意味著最大寬度或最大高度會設(shè)置為double.INFINITY。
一個本身試圖占用盡可能大的渲染盒在給定無邊界約束時不會有用,在檢查模式下(譯者語:指Dart的checked模式),會拋出異常。
渲染盒具有無邊界約束的最常見情況是在自身處于彈性盒(Row 和 Column)內(nèi)以及可滾動區(qū)域 (ListView 和其他ScrollView的子類)內(nèi)。
特別是,ListView試圖擴(kuò)充以適應(yīng)其橫向可用空間(即,如果它是一個垂直滾動塊,它將嘗試與其父項一樣寬)。 如果您ListView在水平滾動的情況下嵌套垂直滾動的ListView,則內(nèi)部滾動區(qū)域會盡可能寬,這是無限寬的,因為外部滾動區(qū)域可以在水平方向上一直滾動。
彈性盒自身(Row和Column) 的行為有所不同,這取決于它們在給定的方向上是處于有邊界的限制還是無邊界的限制下。
在有邊界的限制下,他們在這個方向上會盡可能大。
在無邊界的限制下,他們試圖讓自己的子節(jié)點(diǎn)在這個方向自適應(yīng)。 在這種情況下,您不能將子節(jié)點(diǎn)的flex屬性設(shè)置為0以外的任何值(默認(rèn)值為0)。 在widget庫中,這意味著一個彈性盒位于另一個彈性盒或可滾動的盒子內(nèi)部時,你不能使用Expanded。 如果你這樣做,你會得到一個異常消息。
在 交叉 方向上, 例如在Column的寬度和在Row的高度上,它們絕不能是無界的,否則它們將無法合理地對齊他們的子節(jié)點(diǎn)。
更多建議: