W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
尺寸限制類容器用于限制容器大小,F(xiàn)lutter 中提供了多種這樣的容器,如ConstrainedBox
、SizedBox
、UnconstrainedBox
、AspectRatio
等,本節(jié)將介紹一些常用的。
ConstrainedBox
用于對(duì)子組件添加額外的約束。例如,如果你想讓子組件的最小高度是80像素,你可以使用const BoxConstraints(minHeight: 80.0)
作為子組件的約束。
我們先定義一個(gè)redBox
,它是一個(gè)背景顏色為紅色的盒子,不指定它的寬度和高度:
Widget redBox=DecoratedBox(
decoration: BoxDecoration(color: Colors.red),
);
我們實(shí)現(xiàn)一個(gè)最小高度為 50,寬度盡可能大的紅色容器。
ConstrainedBox(
constraints: BoxConstraints(
minWidth: double.infinity, //寬度盡可能大
minHeight: 50.0 //最小高度為50像素
),
child: Container(
height: 5.0,
child: redBox
),
)
運(yùn)行效果如圖5-2所示:
可以看到,我們雖然將 Container 的高度設(shè)置為 5 像素,但是最終卻是 50 像素,這正是 ConstrainedBox 的最小高度限制生效了。如果將 Container 的高度設(shè)置為 80 像素,那么最終紅色區(qū)域的高度也會(huì)是 80 像素,因?yàn)樵诖耸纠?,ConstrainedBox 只限制了最小高度,并未限制最大高度。
BoxConstraints用于設(shè)置限制條件,它的定義如下:
const BoxConstraints({
this.minWidth = 0.0, //最小寬度
this.maxWidth = double.infinity, //最大寬度
this.minHeight = 0.0, //最小高度
this.maxHeight = double.infinity //最大高度
})
BoxConstraints 還定義了一些便捷的構(gòu)造函數(shù),用于快速生成特定限制規(guī)則的 BoxConstraints,如BoxConstraints.tight(Size size)
,它可以生成給定大小的限制;const BoxConstraints.expand()
可以生成一個(gè)盡可能大的用以填充另一個(gè)容器的 BoxConstraints。除此之外還有一些其它的便捷函數(shù),讀者可以查看API文檔 (opens new window)。
SizedBox
用于給子元素指定固定的寬高,如:
SizedBox(
width: 80.0,
height: 80.0,
child: redBox
)
運(yùn)行效果如圖5-3所示:
實(shí)際上SizedBox
只是ConstrainedBox
的一個(gè)定制,上面代碼等價(jià)于:
ConstrainedBox(
constraints: BoxConstraints.tightFor(width: 80.0,height: 80.0),
child: redBox,
)
而BoxConstraints.tightFor(width: 80.0,height: 80.0)
等價(jià)于:
BoxConstraints(minHeight: 80.0,maxHeight: 80.0,minWidth: 80.0,maxWidth: 80.0)
而實(shí)際上ConstrainedBox
和SizedBox
都是通過(guò)RenderConstrainedBox
來(lái)渲染的,我們可以看到ConstrainedBox
和SizedBox
的createRenderObject()
方法都返回的是一個(gè)RenderConstrainedBox
對(duì)象:
@override
RenderConstrainedBox createRenderObject(BuildContext context) {
return new RenderConstrainedBox(
additionalConstraints: ...,
);
}
如果某一個(gè)組件有多個(gè)父級(jí)ConstrainedBox
限制,那么最終會(huì)是哪個(gè)生效?我們看一個(gè)例子:
ConstrainedBox(
constraints: BoxConstraints(minWidth: 60.0, minHeight: 60.0), //父
child: ConstrainedBox(
constraints: BoxConstraints(minWidth: 90.0, minHeight: 20.0),//子
child: redBox,
)
)
上面我們有父子兩個(gè)ConstrainedBox
,他們的限制條件不同,運(yùn)行后效果如圖5-4所示:
最終顯示效果是寬 90,高 60,也就是說(shuō)是子ConstrainedBox
的minWidth
生效,而minHeight
是父ConstrainedBox
生效。單憑這個(gè)例子,我們還總結(jié)不出什么規(guī)律,我們將上例中父子限制條件換一下:
ConstrainedBox(
constraints: BoxConstraints(minWidth: 90.0, minHeight: 20.0),
child: ConstrainedBox(
constraints: BoxConstraints(minWidth: 60.0, minHeight: 60.0),
child: redBox,
)
)
運(yùn)行效果如圖5-5所示:
最終的顯示效果仍然是 90,高 60,效果相同,但意義不同,因?yàn)榇藭r(shí)minWidth
生效的是父ConstrainedBox
,而minHeight
是子ConstrainedBox
生效。
通過(guò)上面示例,我們發(fā)現(xiàn)有多重限制時(shí),對(duì)于minWidth
和minHeight
來(lái)說(shuō),是取父子中相應(yīng)數(shù)值較大的。實(shí)際上,只有這樣才能保證父限制與子限制不沖突。
思考題:對(duì)于
maxWidth
和maxHeight
,多重限制的策略是什么樣的呢?
UnconstrainedBox
不會(huì)對(duì)子組件產(chǎn)生任何限制,它允許其子組件按照其本身大小繪制。一般情況下,我們會(huì)很少直接使用此組件,但在"去除"多重限制的時(shí)候也許會(huì)有幫助,我們看下下面的代碼:
ConstrainedBox(
constraints: BoxConstraints(minWidth: 60.0, minHeight: 100.0), //父
child: UnconstrainedBox( //“去除”父級(jí)限制
child: ConstrainedBox(
constraints: BoxConstraints(minWidth: 90.0, minHeight: 20.0),//子
child: redBox,
),
)
)
上面代碼中,如果沒(méi)有中間的UnconstrainedBox
,那么根據(jù)上面所述的多重限制規(guī)則,那么最終將顯示一個(gè) 90×100 的紅色框。但是由于UnconstrainedBox
“去除”了父ConstrainedBox
的限制,則最終會(huì)按照子ConstrainedBox
的限制來(lái)繪制redBox
,即 90×20:
但是,讀者請(qǐng)注意,UnconstrainedBox
對(duì)父組件限制的“去除”并非是真正的去除:上面例子中雖然紅色區(qū)域大小是 90×20,但上方仍然有80的空白空間。也就是說(shuō)父限制的minHeight
(100.0)仍然是生效的,只不過(guò)它不影響最終子元素redBox
的大小,但仍然還是占有相應(yīng)的空間,可以認(rèn)為此時(shí)的父ConstrainedBox
是作用于子UnconstrainedBox
上,而redBox
只受子ConstrainedBox
限制,這一點(diǎn)請(qǐng)讀者務(wù)必注意。
那么有什么方法可以徹底去除父ConstrainedBox
的限制嗎?答案是否定的!所以在此提示讀者,在定義一個(gè)通用的組件時(shí),如果要對(duì)子組件指定限制,那么一定要注意,因?yàn)橐坏┲付ㄏ拗茥l件,子組件如果要進(jìn)行相關(guān)自定義大小時(shí)將可能非常困難,因?yàn)樽咏M件在不更改父組件的代碼的情況下無(wú)法徹底去除其限制條件。
在實(shí)際開(kāi)發(fā)中,當(dāng)我們發(fā)現(xiàn)已經(jīng)使用SizedBox
或ConstrainedBox
給子元素指定了寬高,但是仍然沒(méi)有效果時(shí),幾乎可以斷定:已經(jīng)有父元素已經(jīng)設(shè)置了限制!舉個(gè)例子,如 Material 組件庫(kù)中的AppBar
(導(dǎo)航欄)的右側(cè)菜單中,我們使用SizedBox
指定了 loading 按鈕的大小,代碼如下:
AppBar(
title: Text(title),
actions: <Widget>[
SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(
strokeWidth: 3,
valueColor: AlwaysStoppedAnimation(Colors.white70),
),
)
],
)
上面代碼運(yùn)行后,效果如圖5-7所示:
我們會(huì)發(fā)現(xiàn)右側(cè) loading 按鈕大小并沒(méi)有發(fā)生變化!這正是因?yàn)?code>AppBar中已經(jīng)指定了actions
按鈕的限制條件,所以我們要自定義 loading 按鈕大小,就必須通過(guò)UnconstrainedBox
來(lái)“去除”父元素的限制,代碼如下:
AppBar(
title: Text(title),
actions: <Widget>[
UnconstrainedBox(
child: SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(
strokeWidth: 3,
valueColor: AlwaysStoppedAnimation(Colors.white70),
),
),
)
],
)
運(yùn)行后效果如圖5-8所示:
生效了!
除了上面介紹的這些常用的尺寸限制類容器外,還有一些其他的尺寸限制類容器,比如AspectRatio
,它可以指定子組件的長(zhǎng)寬比、LimitedBox
用于指定最大寬高、FractionallySizedBox
可以根據(jù)父容器寬高的百分比來(lái)設(shè)置子組件寬高等,由于這些容器使用起來(lái)都比較簡(jiǎn)單,我們便不再贅述,讀者可以自行了解。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: