Flutter中可以經(jīng)呈渭埃看到的控件Container,所以我們這篇文章開(kāi)始細(xì)致介紹一下Container.
1 簡(jiǎn)介
A convenience widget that combines common painting, positioning, and sizing widgets.
Container在Flutter開(kāi)發(fā)中非常常見(jiàn),官方給出的簡(jiǎn)介是一個(gè)結(jié)合了繪制(painting),定位(positioning),以及尺寸(sizing)widget的widget.
通過(guò)官方的描述可以得出幾個(gè)信息,它是一個(gè)組合的widget弟孟,內(nèi)部有繪制widget、定位widget、尺寸widget。后續(xù)看到的不少widget呆躲,都是通過(guò)一些更基礎(chǔ)的widget組合而成的。
1.1 Container的組成
Container的組成:
- 最里面的是child元素;
- child元素首先會(huì)被padding包裹著;
- 然后添加額外的constrainits限制;
- 最后添加margin;
Container的繪制過(guò)程:
- 首先會(huì)繪制transform效果;
- 接著繪制decoration;
- 然后繪制child;
- 最后繪制foregroundDecoration;
Container自身尺寸的調(diào)節(jié)分兩種情況:
- Container再看沒(méi)有子節(jié)點(diǎn)(children)的時(shí)候,會(huì)試圖去變得足夠大.除非constraints是unbounded限制,在這種情況下,Container會(huì)試圖變得足夠小.
- 帶子節(jié)點(diǎn)的Container,會(huì)根據(jù)子節(jié)點(diǎn)尺寸調(diào)節(jié)自身尺寸,但是Container構(gòu)造器中如果包含了width捶索、height以及constraints,則會(huì)按照構(gòu)造器中的參數(shù)來(lái)進(jìn)行尺寸調(diào)節(jié).
1.2 布局
Container組合了一系列的widget,這些widget都有自己的布局行為,因此Container的布局行為會(huì)比較復(fù)雜.
一般情況下插掂,Container會(huì)遵循如下順序去嘗試布局:
- 對(duì)齊(alignment);
- 調(diào)節(jié)自身尺寸適合子節(jié)點(diǎn);
- 擴(kuò)展自身去適應(yīng)父節(jié)點(diǎn);
- 調(diào)節(jié)自身到足夠小;
進(jìn)一步說(shuō):
- 如果沒(méi)有子節(jié)點(diǎn)、沒(méi)有設(shè)置width腥例、height以及constraints辅甥,并且父節(jié)點(diǎn)沒(méi)有設(shè)置unbounded的限制,Container會(huì)將自身調(diào)整到足夠小.
- 如果沒(méi)有子節(jié)點(diǎn)院崇、對(duì)齊方式(alignment),但是提供了width袍祖、height或者constraints底瓣,那么Container會(huì)根據(jù)自身以及父節(jié)點(diǎn)的限制,將自身調(diào)節(jié)到足夠小.
- 如果沒(méi)有子節(jié)點(diǎn)蕉陋、width捐凭、height、constraints以及alignment凳鬓,但是父節(jié)點(diǎn)提供了bounded限制茁肠,那么Container會(huì)按照父節(jié)點(diǎn)的限制,將自身調(diào)整到足夠大.
- 如果有alignment缩举,父節(jié)點(diǎn)提供了unbounded限制垦梆,那么Container將會(huì)調(diào)節(jié)自身尺寸來(lái)包住child.
- 如果有alignment,并且父節(jié)點(diǎn)提供了bounded限制仅孩,那么Container會(huì)將自身調(diào)整的足夠大(在父節(jié)點(diǎn)的范圍內(nèi))托猩,然后將child根據(jù)alignment調(diào)整位置.
- 含有child,但是沒(méi)有width辽慕、height京腥、constraints以及alignment,Container會(huì)將父節(jié)點(diǎn)的constraints傳遞給child溅蛉,并且根據(jù)child調(diào)整自身.
1.3 繼承關(guān)系
Object > Diagnosticable > DiagnosticableTree > Widget > StatelessWidget > Container
從繼承關(guān)系可以看出公浪,Container是一個(gè)StatelessWidget。Container并不是一個(gè)最基礎(chǔ)的widget船侧,它是由一系列的基礎(chǔ)widget組合而成欠气。
2. 源碼解析
構(gòu)造函數(shù)如下:
Container({
Key key,
this.alignment,
this.padding,
Color color,
Decoration decoration,
this.foregroundDecoration,
double width,
double height,
BoxConstraints constraints,
this.margin,
this.transform,
this.child,
})
2.1 屬性解析
- key:Container唯一標(biāo)識(shí)符,用于查找更新.
- alignment:控制child的對(duì)齊方式镜撩,如果container或者container父節(jié)點(diǎn)尺寸大于child的尺寸晃琳,這個(gè)屬性設(shè)置會(huì)起作用,有很多種對(duì)齊方式.
- padding:decoration內(nèi)部的空白區(qū)域,如果有child的話卫旱,child位于padding內(nèi)部人灼。padding與margin的不同之處在于,padding是包含在content內(nèi)顾翼,而margin則是外部邊界投放,設(shè)置點(diǎn)擊事件的話,padding區(qū)域會(huì)響應(yīng)适贸,而margin區(qū)域不會(huì)響應(yīng).
- color:用來(lái)設(shè)置container背景色灸芳,如果foregroundDecoration設(shè)置的話,可能會(huì)遮蓋color效果.
- decoration:繪制在child后面的裝飾拜姿,設(shè)置了decoration的話烙样,就不能設(shè)置color屬性,否則會(huì)報(bào)錯(cuò)蕊肥,此時(shí)應(yīng)該在decoration中進(jìn)行顏色的設(shè)置.
- foregroundDecoration:繪制在child前面的裝飾.
- width:container的寬度谒获,設(shè)置為double.infinity可以強(qiáng)制在寬度上撐滿,不設(shè)置壁却,則根據(jù)child和父節(jié)點(diǎn)兩者一起布局.
- height:container的高度批狱,設(shè)置為double.infinity可以強(qiáng)制在高度上撐滿.
- constraints:添加到child上額外的約束條件.
- margin:圍繞在decoration和child之外的空白區(qū)域,不屬于內(nèi)容區(qū)域.
- transform:設(shè)置container的變換矩陣展东,類型為Matrix4.
- child:container中的內(nèi)容widget.
例如:
new Container(
constraints: BoxConstraints.expand(
height:Theme.of(context).textTheme.display1.fontSize * 1.1 + 200.0,
),
decoration: BoxDecoration(
border: Border.all(width: 2.0, color: Colors.red),
color: Colors.grey,
borderRadius: BorderRadius.all(new Radius.circular(20.0)),
image: DecorationImage(
image: NetworkImage('http://h.hiphotos.baidu.com/zhidao/wh%3D450%2C600/sign=0d023672312ac65c67506e77cec29e27/9f2f070828381f30dea167bbad014c086e06f06c.jpg'),
centerSlice: Rect.fromLTRB(270.0, 180.0, 1360.0, 730.0),
),
//這是一個(gè)漸變顏色的屬性,在使用時(shí)注意不能設(shè)置container的color,否則會(huì)報(bào)錯(cuò).
//gradient: const LinearGradient(
// colors: [Colors.purple,Colors.green,Colors.cyanAccent],
// ),
),
padding: const EdgeInsets.all(8.0),
alignment: Alignment.center,
child: Text('Hello World',
style: Theme.of(context).textTheme.display1.copyWith(color: Colors.black)),
transform: Matrix4.rotationZ(0.3),
)
其中decoration可以設(shè)置邊框赔硫、背景色、背景圖片盐肃、圓角等屬性爪膊,非常實(shí)用。對(duì)于transform這個(gè)屬性砸王,一般有過(guò)其他平臺(tái)開(kāi)發(fā)經(jīng)驗(yàn)的惊完,都大致了解,這種變換处硬,一般不是變換的實(shí)際位置小槐,而是變換的繪制效果,也就是說(shuō)它的點(diǎn)擊以及尺寸荷辕、間距等都是按照未變換前的.
想了解更多Flutter學(xué)習(xí)知識(shí)請(qǐng)聯(lián)系:QQ(814299221)